Table of Contents

  • Introduction

  • Part 1. Desktop

  • Ch1. HTML5 and its New APIs

  • Ch2. Advanced Intro to JavaScript

  • Ch3. Mocking Up the “Save Sick Child” Web Site

  • Ch4. Using Ajax and JSON]

  • Ch5. Test-Driven Development with JavaScript

  • Ch6. "Save Sick Child with JQuery framework

  • Ch7. "Save a Child" with Ext JS framework

  • Ch8. Replacing HTTP with WebSockets

  • Ch9. Securing Web Applications

  • Ch10. Large Scale JavaScript Projects

  • Part 2. Mobile

  • Ch11. Responsive Design: One Site Fits All

  • Ch12. «Save a Child» With JQuery Mobile

  • Ch13. «Save a Child» with Sencha Touch

  • Ch14. Hybrid Applications: HTML + Native API

Introduction

This is a home of the upcoming book «Enterprise Web Development. From Desktop to Mobile». The authors of this book are Yakov Fain, Victor Rasputnis, Viktor Gamov, and Anatole Tartakovsky. They all work for Farata Systems.

This book will be printed in the Summer of 2013, but you can enjoy read the current manuscript enterprisewebbook.com. The sources of this book are located at Github.

The book is released under a Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported license meaning you can both get a copy of the book for free or help to further improve it. This book will be printed and available for purchase via O’Reilly Media. Readers will have an option of purchasing this book in a number of digital formats.

What’s an Enterprise Web Application?

This book has the word Enterprise in its title, which needs to be explained, and we’ll do it by examples. Creating a Web application that will process orders is not the same as creating a Web site to publish blogs. Enterprise applications include company-specific workflows, and usually they need to be integrated with number of internal systems, data sources and processes.

Google Doc is not an enterprise Web application. But Google appliance integrating search operating on company documents, databases, processes, tickets, and providing collaboration is - it integrates consumer-workforce front office with what the company does (back office).

Google Maps is not an enterprise application. But Google Maps integrated with the company site used by insurance agents to plan daily route, scheduling, doing address verification and geo-coding is.

Just using a Web application in some business doesn’t make it an enterprise Web application. If you take Gmail as is, it won’t be an enterprise application until you integrate it into another process of your business.

Is an online game an enterprise application? It depends on the game. A multi-player online roulette game hooked up to a payment system, and maintaining users' accounts is an enterprise Web application. But playing Sudoku online doesn’t feel too enterprisey.

How about a dating Web site? If the site just offers an ability to display singles - it’s just a publishing site as there is not much of a business there. Can you turn a dating Web site into an enterprise application? It’s possible.

Some people will argue that an enterprise application must supports multiple users, high data load, be scalable, have business and persistence layers, offer professional support et al. We don’t believe that a Web application should do all this to qualify for the adjective enterprise.

Let’s create a simple definition of an enterprise Web application:

"An enterprise Web application is the one that helps an organization running its business online"

In this book we are going to build a Save the Child Web application that will allow people to register, donate, find local kids that need help, match donors and recipients, upload images, videos and display statistics. Would these feature make Save the Child an enterprise Web application? Yes, our non-for-profit organization that collects donations for ill kids is our enterprise.

During the last decade the authors of this book worked on many enterprise Web applications using variety of programming languages and frameworks: HTML, JavaScript, Java, and Flex to name a few. Apache Flex and Java produce compiled code that runs in a well known and predictable virtual machine (JVM and Flash Player respectively).

This book is about developing software using what’s known as HTML5 stack. But only the first chapter of this book will offer you an overview of the selected HTML5 tags and APIs. The second chapter is an advanced introduction to JavaScript. The rest of the chapters are about designing, re-designing, developing, and re-developing a sample Web site Save Sick Child. You’ll be learning whatever is required for building this Web application on the go.

You’ll be using dynamic HTML (DHTML), which is HTML5, JavaScript, and Cascading Style Sheets (CSS). We’ll add to the mix the XMLHttpRequest object that lives in a Web browser and communicates with the server without the need to refresh the entire Web page (a.k.a. AJAX). JSON will be our data format of choice for data exchange between the Web browser and the server.

Warning It’s not possible to provide the detailed coverage of all programming languages, frameworks and tools used in this rather short book. You’ll need to do some additional reading with more in-depth coverage of certain topics. This book is for practitioner who need to learn while developing a project.

From DHTML to HTML5

DHTML has been introduced in Microsoft Internet Explorer (IE) 5, and several years later it was substituted with a more popular acronym AJAX. Back in 1999 Microsoft introduced XMLHttpRequest object to allow the Web version of their mail client Outlook to update the browser’s window without the need to refresh the entire Web page. The market share of IE5 was about 90% at the time, and in enterprises it was literally the only approved browser.

Many years passed by and today’s Internet ecosystems changed quite a bit. Web browsers are a lot smarter and performance of JavaScript improved substantially. The browsers support 6-8-12 simultaneous connections per domain (as opposed to 2 five years ago), which gave a performance boost to all AJAX applications. At least one third of all Web requests is being made from smart phones or tablets. Apple Inc. started their war against browser’s plugins hence using embedded Java VM or Flash Player is not an option there. The growing need to support a huge variety of mobile devices gave another boost for HTML5 stack, which is supported by all devices.

But choosing HTML5 as the least common denominator that works in various devices and browsers means lowering requirements for your enterprise project. From the very beginning parameters like reliability, ability to adapt to different the screen sizes and densities will be simplified comparing to developing for one specific VM, device or OS. Instead of implementing these features, the functional specification will include testing under several Web browsers, in many different screen sizes and resolutions. HTML5 developers spend a lot more time in the debugger that people who develop for a known VM. Get ready to solving problems like a dropdown does not show any data in one browser while working fine in all others. Can you imagine a situation when the click event is not always generated while working in Java, Flex, or Silverlight? Get ready for such surprises while testing your DHTML application.

You’ll save some time because there is no need to compile JavaScript, but you’ll spend more time testing deployed code. The final deliverable of an HTML5 project may have as low as half of the functionality comparing to the same project developed for a VM. But you’ll gain a little better Web adaptability, easier implementation of full text search and mashups. The integration with other technologies will also become easier with HTML/JavaScript. If all these advantages are important to your application choose HTML5.

JavaScript will enforce its limitations on any serious and complex enterprise project. You can develop a number of fairly independent windows, but creating a well tested and reliable HTML5 takes time.

In this book we’ll be using some JavaScript frameworks - the are dozens of those on the market. Several of them promise to cover all the needs of your Web application. Overall, there are two main categories of frameworks:

a) Those that allow you to take an existing DHTML Web site and easily add new attributes to all or some page elements so they would start shining, blinking, or do some other fun stuff. Such frameworks don’t promote component-based development. They may not include navigation components, grids, trees, which are pretty typical for any UI of the corporate tasks. JQuery is probably the best representative of this group- it’s light (30Kb), extendable, and easy to learn.

b) Another group of frameworks offers rich libraries of high-level components and allow you to extend them.But overall, such components are supposed to be used together becoming a platform for your Web UI. These components process some events, offer support of the Model-View-Controller paradigm, have a proprietary way of laying out elements on the Web page, organize navigation et al. Ext JS from Sencha belongs to this group.

We’ll use both JQuery and Ext JS and will show you how to develop Web applications with each of these popular frameworks. JQuery is good for improving an existing JavaScript site. JQuery can be used to program about 80% of a Web site. You should use it for the look and feel support, which is what it’s meant for. But you can’t use it for building your application component model. The component model of Ext JS is applicable in about 20% of a Web site, which includes an application piece rather than just being a set of Web pages. Typically it’s a serious view navigator or a wizard to implement a serious business process or a workflow that includes a client’s part.

JavaScript frameworks are hiding from software developers all incompatibilities and take care of the cases when a Web browser doesn’t support some HTML5, CSS3, or JavaScript features yet.

High-level UI components and a workflow support are needed for a typical enterprise application where the user needs to perform several steps to complete the business process. And these 20% of an application’s code will require 80% of the project time of complex development. So choosing a framework is not the most difficult task. The main problem with DHTML projects is not how to pick the best JavaScript framework for development, but finding the right software developers. Lack of qualified developers increases the importance of using specialized frameworks for code testing. The entire code base must be thoroughly tested over and over again. We’ll discuss this subject in the Chapter 5 dedicated to test-driven development.

A JavaScript developer has to remember all unfinished pieces of code. Many things that we take for granted with compiled languages simply don’t exist in JavaScript. For example, in Java or C# just by looking at the method signature you know what are the data types of the method’s parameters. In JavaScript you can only guess if the parameter names are self descriptive. Take the Google’s framework GWT that allows developers write code in Java with auto-generation of the JavaScript code. Writing code in one language with further conversion and deployment in another one is a controversial idea unless the source and generated languages are very similar. We’re not big fans of GWT, because after writing the code you’ll need to be able to debug it. This is when a Java developer meets a foreign language JavaScript.The ideology and psychology of programming in JavaScript and Java are different. A person who writes in Java/GWT has to know how to read and interpret deployed JavaScript code. On the other hand, using TypeScript or CoffeeScript to produce JavaScript code can be a time saver.

The Ext JS framework creators decided to extend JavaScript introducing their version of classes and more familiar syntax for object-oriented languages. Technically they are extending or replacing the constructs of the JavaScript itself extending the alphabet. Ext JS recommends creating objects using ext.create instead of the operator new. But Ext JS is still a JavaScript framework.

JQuery framework substantially simplifies working with browser’s DOM elements and there are millions of small components that know how to do one thing well, for example, an image slider. But it’s still JavaScript and requires developers to understand the power of JavaScript functions, callbacks, and closures.

Should we develop in HTML5 if its standard is not finalized yet?

The short answer is yes. If you are planning to develop mainly for the mobile market, it’s well equipped with the latest Web browsers and if you’ll run into issues there. they won’t be caused by the lack of HTML5 support. In the market of the enterprise Web applications, the aging Internet Explorer 8 is still being widely used and they don’t support some of the HTML5 specific features. But it’s not a show stopper either.If you are using one of the JavaScript frameworks that offers cross-browser compatibility, most likely, they take care of IE8 issues.

The more conservative approach to achieving the browser compatibility is not by relying on the framework promises, but by testing and adjusting your application in different browsers. The chances are that you may need to be fixing the framework’s code here and there. Maintaining compatibility is a huge challenge for any framework’s vendor, which in some cases can consist of just one developer. You shouldn’t have hard feelings against the developers behind the framework of your choice. These guys simply don’t have time to fix everything. You need to form an attitude that a JavaScript framework is similar to a good Legos set that will require your creativity too. Don’t get angry. Cure the framework. Spend some time working on the framework, and then work on your application code. Ideally, submit your fixes back to the framework’s code base - most of them are open source.

If you are planning to write pure JavaScript, add a tiny framework Modernizr to your code base, which will detect if a certain feature is supported by the user’s Web browser, and if not - provide an alternative solution. We like the analogy with TV sets. People with latest 3D HD TV sets and those who have 50-year old black and white televisions can watch the same movie even though the quality of the picture will be drastically different.

Summary

If you are starting working on your first HTML5 enterprise project, get ready to solve the same tasks as Java, JavaFX, Silverlight, or Flexdevelopers face:

  • Reliability of the network communications. What if the data never arrive from/to the server? Is it possible to recover the lost data? Where they got lost? Can we re-send the lost data? What to do with duplicates?

  • Modularization of your application. If your application has certain rarely used menus don’t even load the code that handles this menu.

  • Perceived performance. How quickly the main window of your application is loaded to the user’s computer? How heavy is the framework’s code base?

  • Should you store the application state on the server or on the client?

  • Does the framework offer a rich library of components?

  • Does the framework support creation of loosely coupled application components? Is the event model well designed?

  • Does the framework of your choice cover most of the needs of your application, or you’ll need to use several frameworks?

  • Is well written documentation available?

  • Does the framework of your choice locks you in? Does it restrict your choices? Can you easily replace this framework with another one if need be?

  • Is there an active community to ask for help with technical questions?

We could continue adding items to this list. But our main message is that developing HTML5 applications is not just about adding tag video and canvas to a Web page. It’s about serious JavaScript programming.

Part 1: Desktop

Chapter 1. HTML5 and its New APIs

This is the first and only chapter in this book that’s dedicated to HTML5. You’ll get familiar with some new HTML tags that were introduced to make the markup more semantic and convenient. We’ll also provide a brief overview of selected APIs that are included in HTML5 spec (Web Storage, WebSQL, Web Sockets, and Web Workers).

The majority of the modern Web browsers already support the current version of HTML5 specification. The question is if the users of your Web application have or rather can have a modern browser installed on their device? There are two groups of users that will stick to the outdated browsers for some time:

  1. Computer illiterate people who are afraid of installing any new software one their PCs. Especially, people of the older generation. "John, after the last visit of our grandson our computer works even slower than before. Please don’t let him install these new fancy browsers here. I just need my old Internet Explorer, access to Hotmail and Facebook".

  2. Business users working for large corporations, where all the installations of the software on their PCs is done by professional system administrators. They say, "We have 50000 PCs in or firm. An upgrade from Internet Explorer version 8 to version 9 is a major undertaking. Internal users work with about a hundred Web applications on a regular basis. They can install whatever browser they want, but if some of these application won’t work as expected, the users will flood us with support requests we’re not qualified to resolve . Hence the strategy of using the lowest denominator browser often wins.

In the worst case scenario, Web developers need to make both of these groups happy. Take an online banking - this old couple has to be able to use your Web application from their old PCs otherwise they can transfer their lifetime savings to a different bank which doesn’t require the later version of Firefox for online banking.

Does it mean that enterprise Web developers shouldn’t even bother using HTML5 that’s not 100% supported? Not at all. This means that a substantial portion of their application’s code will be will be bloated by the if-statements figuring out what this specific Web browser supports and providing several solutions that keep your application on float in any Web browser. This what makes the job of DHTML developers a lot more difficult than of, say Java developers who know exactly the environment where their code will work. Of you don’t install the JavaRuntime of version 1.6 our application won’t work. As simple as that. How about asking Java developers writing applications that will work in any runtime released during the last 10 years? No, we’re not that nasty.

Do you believe it would be a good idea for Amazon or Facebook to re-write their UI in Java? Of course not unless they want to loose half of their customers who will be scared to death after seeing the message of the 20-step Java installer asking for the access to the internals of their computer. Each author of this book is a Java developer, and we love using Java… on the server side. But when it comes to the consumer facing Web applications it’s just not there yet.

So what’s the bottom line? We have to learn how to develop Web applications that won’t require installing any new software on the user’s machines. Today it’s DHTML or, let’s stick to the modern terminology, HTML5 stack.

In the unfortunate event of needing to support both new and old HTML and CSS implementations you can use HTML5 Boilerplate that is not a framework, but a template for creating a new HTML project that will support HTML5 and CSS3 elements but will work even in the hostile environments of the older browsers. It’s like broadcasting a TV show in HD, but letting the cavemen with the 50-year old black-and-white tubes watching it too.

HTML Boilerplate comes is a really simple way to start your project pre-packaged with solutions and workarounds offered by well known gurus in the industry. Make no mistake, your codebase may be larger that you wanted - for example, the initial CSS starts with 500 lines accommodating the old and new browsers, but it may be your safety net.

Tip Watch this screencast by Paul Irish, a co-creator of HTML5 Boilerplate. You can also read the current version of the Getting started with HTML5 Boilerplate on Github.

Overview of Selected HTML 5 Tags

In this section we’ll overview a small set of the new HTML5 tags and attributes that are very practical for enterprise Web developers. For example, we are not going to review the <canvas> tag that allows you to draw freely in a predefined rectangular area. But we will show you some HTML5 goodies that are practical and useful for Web forms.

HTML5 Forms: Brief Overview

It’s hard to imagine an enterprise Web application that is not using forms. At the very minimum the Contact Us form has to be there. A login view is yet another example of the HTML form that almost every enterprise application needs. Our sample application Save Sick Child will need it too.

We’ll start with the prompts. Showing the hints or prompts right inside the input field will save you some screen space. HTML5 has a special attribute placeholder.

HTML5 New APIs

TODO

Chapter 2. Advanced Introduction to JavaScript

This chapter is dedicated to the JavaScript programming language. Our challenging goal is "From Zero to Hero in 50 pages". While in the future chapters you’ll see how JavaScript frameworks can greatly minimize the amount of the JavaScript code that you need to write manually, you still need to understand the language itself.

This chapter starts with basics of the language, but then it quickly progresses to such advanced topics as prototypal inheritance, callbacks, and closures. If you prefer fat manuals covering each and every detail of programming languages, we can recommend you the book "JavaScript: The Definite Guide", Sixth Edition by David Flanagan.

Besides the JavaScript coverage this chapter includes a section on the tools (IDEs, debuggers, Web inspectors et al.) that will make your development process more productive.

Important While you can skip some sections of this book as not relevant to your needs, we recommend you to read each section of this chapter in order. Most of the materials presented here expect you to understand the previous content of this chapter.

JavaScript: A Brief History

The JavaScript programming language was designed in 1995 by Brendan Eich, who was working for Netscape Communications Corporation at the time. His goal was to allow developers create more interactive Web pages. Initially the name of this language was Mocha, then LiveScript, and finally Netscape agreed with Sun Microsystems, creator of Java to rename it to JavaScript.

A year later, the language was given to an international standards body called ECMA, which formalized the language into ECMAScript standard so that other Web browser vendors could create their implementation of this standard. JavaScript is not the only language created based on the ECMAScript specification - ActionScript is a good example of another popular dialect of ECMAScript.

To learn more about the history of JavaScript from the source watch the Brendan Eich’s presentation "JavaScript at 17" at O’Reilly’s conference Fluent 2012.

Vast majority of today’s JavaScript code is being executed by the Web browsers, butthere are JavaScript engines that can execute JavaScript code independently. For example, Google’s V8 JavaScript engine implements ECMAScript 5 and is used not only in the Chrome browser, but can run in a standalone mode and can be embedded in any C++ application. Using the same programming language on the client and the server is the main selling point of node.js, which runs in V8. Oracle’s Java Development Kit (JDK) 8 will include the JavaScript engine Nashorn that not only can run on both the server and the client computers, but also allows to embed the fragments of JavaScript into Java programs.

In the 90th, JavaScript was considered a second class language used mainly for prettifying Web pages. In 2005 the techniques known as AJAX (see Chapter 4) made a significant impact to the way Web pages were built. With AJAX, the specific content inside the Web page could be updated without the need to make a full page refresh. For example, Google’s gmail that inserts just one line at the top of your input box whenever the new email arrives - it doesn’t re-retrieve the entire content of your Inbox from the server.

AJAX gave a second birth to JavaScript. But the vendors of Web browsers were not eager to implement the latest specifications of ECMAScript. Browsers’ incompatibility and lack of good development tools prevented JavaScript from becoming the language of choice for Web applications. Let’s not forget about the ubiquitous Flash Player – an excellent VM supported by all desktop Web browsers. Rich Internet Applications written in ActionScript were compiled into the byte code and executed by Flash Player on the user’s machine inside the Web browser.

If AJAX saved JavaScript, then rapid proliferation of tablets and smartphones made it really hot. Today’s mobile devices come equipped with modern Web browsers, and in the mobile world there is no need to make sure that your Web application will work in the 4-year old Internet Explorer 8. Adobe’s decision to stop supporting Flash Player in the mobile Web browsers is yet another reason to turn to JavaScript if your Web application has to be accessed from smartphones or tablets.

ECMASript, 5th Edition has been published in 2009 and is currently supported by all modern Web browsers. If you are interested in discovering if specific features of ECMAScript 5 are supported by a particular Web browser, check the latest version of the ECMAScript 5 compatibility table. At the time of this writing the snapshot of the Chrome Browser v. 22 looks as in [FIG2-1] below:

images/fig_02_01.jpg
Figure 1. ECMAScript 5 Compatibility Sample Chart

JavaScript became the lowest common denominator available on thousands of different devices. Yes, the JavaScript engines are not exactly the same on thousands devices that people use to login to Facebook, but they are pretty close, and using some of the JavaScript frameworks spare you from worrying about their incompatibilities.

JavaScript is an interpreted language that arrives to the Web browser as text. The JavaScript engine optimizes and compiles the code before the execution. If the JavaScript engine is a part of a Web page, the browser will load and execute the JavaScript code embedded or referenced between the HTML tags <script> and </script>. JavaScript was originally created for Web browsers, which were supposed to display whatever content has successfully arrived. What if an image has not arrived from the server? You’ll see a broken image icon. What if erroneous JavaScript code with syntax errors has arrived to the browser? Well, the engine will try to execute whatever has arrived. The end users may appreciate such browser’s forgiveness when at least some content is available, but the software developers should be ready to spend more time debugging (in multiple browsers) the errors that could have been caught by compilers in other programming languages.

Why Declaring JavaScript Variables

JavaScript is a weakly typed language hence the developers don’t have a luxury of strong compiler’s help that Java or C# developers enjoy. This is easily explainable. Imagine that if in Java or C# instead of declaring variables of specific data types everything would be of type Object, and you could assign to it any value – a string, a number, or a custom object Person. This would substantially complicate the ability of the compiler to weed out all possible errors. You don’t need to declare variables in JavaScript – just assign a value and the JavaScript engine will figure out the proper type during the execution of your code.For example, the variable named girlfriend will have a data type of String:

girlfriendName=“Mary”;

Since I haven’t used the keyword var in front of girlfriend, this variable will have the global scope. Variables declared with var inside functions are local. Consider the following function declaration:

function addPersonalInfo(){
   var address ="123 Main Street";      // local String variable
   age=25;                              // global Number variable
   var isMarried = true;                // local boolean variable
       isMarried = "don't remember";    // now it's of String type
}

The variables address and isMarried are visible only inside the function addPersonalInfo(). The variable age becomes global because of omission of the keyword var. In Chapter 3, you’ll see an example of how to limit the scope of the variables to avoid polluting the global name space.

The variable isMarried changes its type from Boolean to String during the execution of the above script, and JavaScript engine won’t complain assuming that the programmer knows what she’s doing. So be ready for the run-time surprises and allocate a lot more time for testing than with programs written in compiled languages.

Yet another moving part is the JavaScript engine where your code will run. Unless you are developing for strictly controlled enterprise environment you can’t assume that the end-user will have the same runtime as yours. You must test your code in multiple Web browsers.

Which IDE to Use

Selecting an Integrated Development Environment (IDE) that supports JavaScript is a matter of your personal preference. Since there is no compilation stage and most of your debugging will be done using the Web browser tools, picking a text editor that supports syntax highlighting is all that most developers need. For example, there is an excellent commercial text editor Sublime Text 2. Among many programming languages this editor understands the keywords of HTML, CSS, and JavaScript, and it offers not only syntax highlighting, context sensitive help, and auto-complete too.

If you are coming from the Java background, the chances are that you are familiar with free and open sourced Eclipse IDE. In this case install the Eclipse plugin VJET by eBay.

Oracle’s IDE NetBeans 7.3 and above support HTML5 and JavaScript development and includes JavaScript debugger that allows your code to connect to the Web browser, while debugging inside the IDE. If you prefer Microsoft technologies, they offer excellent JavaScript support in Visual Studio 2012.

In this book we’ll use an Eclipse-based Aptana Studio 3 IDE. Aptana Studio is available free of charge. Aptana Studio comes with embedded Web Server so you can test your JavaScript code without the need to start any additional software. In this chapter we’ll use Aptana Studio IDE to illustrate the features of JavaScript, and in the next chapter you’ll be working with a number of Aptana projects that will lead you through the development of the first version of our Save Sick Child Web application.

For the real world development we recommend using commercial IDE WebStorm from JetBrains. In addition to smart context sensitive help, auto-complete, and syntax highlighting it offers HTML5 templates, and the code coverage feature that identifies the code fragment that haven’t been tested. All of the editors and IDEs listed here are either available for free or are priced in the area of $60 USD. Try them all and pick the one that best fits your coding habits.

Getting Familiar with Aptana IDE

Download and install Aptana Studio 3 from http://aptana.com. Start Aptana and close the start page it displays by clicking on the little X on the tab. Then customize the color theme of this IDE by clicking the rainbow-colored circle on its toolbar. We usually select the theme called Eclipse. After the first start of Aptana you’ll see the message on the left side that reads “There are no projects in your workspace. To get started, please create or import an existing one.”

If you want to start playing with the code samples that come with this book, click on the button Import Project, select the General | Archive file. Find the zip file you’d like to use, e.g. chapter2.zip, and press Finish. The project from the selected zip file will be imported into the Aptana’s workspace, which is nothing more than a folder on the disk where the source code will reside. When you work in Aptana IDE you see a set of views (panels). This set is called perspective. For Web projects Aptana uses Web perspective, which is indicated at the top right corner. Pressing the icon with a little pus sign at the top right allows to open another perspective with its own set of views.

Let’s get started with creating a project from scratch by pressing the button Create Project on the left. You could have also created a new Web Project using the File menu. On the next window you’ll need to select a wizard, and we’ll be always working with Web Projects throughout this book. The next window will offer you to select a project template - let’s stick to the simplest one - Default Project. Name it MyFirstProject.

To add an HTML file to this project select the menu File | New From Template | HTML | HTML5 Template. Aptana will offer you new_file.html the name of this file - no need to change it for now. Just press finish and you’ll see a window similar to the one shown on [FIG2-2].

images/fig_02_02.jpg
Figure 2. Aptana IDE with one HTML5 file

Right-click on the new_file.html and select the menu Run as JavaScript Web project. Don’t get upset that there is no JavaScript code there yet - we’ll add it pretty soon. Aptana starts its built-in Web server that by default runs on the port 8020 (it’s configurable in Aptana Preferences). The Web browser opens up and displays the page that looks like the one in [FIG2-3]. Aptana has used its default template to generate HTML file. The template can be changed to your liking, and you can read about it in Aptana’s documentation at http://bitly.com/LRqRdU.

images/fig_02_03.jpg
Figure 3. Running MyFirstProject
Tip To configure the Web Browser that Aptana should open by default, open its Preferences window and select the Web browser of your choice under the General section. Many examples in this chapter use the Firefox with installed add-on Firebug, so start with making Firefox your default browser.

Adding JavaScript to HTML

If your JavaScript is a part of HTML document, typically, you’ll be adding your <script> tags at the end of HTML file. The reason is simple - your JavaScript code may be manipulating with HTML elements, and you want them to exist by the time the script runs. The other way to ensure that the code is not running unless the Web page has loaded is by catching window’s load event, and you’ll see such example later in this chapter in the section on browser’s events. Some JavaScript frameworks may have their own approach to dealing with HTML content and in Chapter 7 you’ll see that the main HTML file of the Web application written with Ext JS framework has <script> tags followed by the empty <body> tags. But let’s keep things simple for now.

Add the following fragment at the very end (right above the closing </body> tag) of the new_file.html from [FIG2-2].

<script>
   alert("Hello from JavaScript");
</script>

Run the new_file.html in Aptana and you’ll see the following output in your Web browser:

images/fig_02_04.jpg
Figure 4. Running MyFirstProject with JavaScript at the bottom

Note that the Alert popup box is shown on top of the Web page that already rendered all of its HTML components. Now move the above code up to the end of the <head> section and re-run new_file.html. The picture is different now - the Alert box is shown before the HTML rendering is complete.

images/fig_02_05.jpg
Figure 5. Running MyFirstProject with JavaScript at the top

In this simple example this doesn’t cause any malfunctioning of the code, but if our JavaScript would need to manipulate with HTML elements, we’d run into issues of accessing non-existent components.

Tip Beside simple Alert box, JavaScript has Confirm and Prompt boxes, which allow asking OK/Cancel type of questions or request some input from the user.

Debugging JavaScript in Web Browsers

The best way to learn any program is to run it step by step through a debugger. While some people appreciate using debuggers offered by Aptana, NetBeans, or Visual Studio, we prefer to debug using great tools offered by the major Web browsers:

  • Firefox: FireBug add-on

  • Chrome: Developer Tools

  • Internet Explorer: F12 Developer Tools

  • Safari: the menu Develop

  • Opera: Dragonfly

We’ll be doing most of the debugging in FireBug or Chrome Developer Tools. Both of them provide valuable information about your code and are easy to use. To get FireBug go to www.getfirebug.com and press the red button Install Firebug and follow the instructions. In Firefox, open the Firebug panel from the menu View.

images/fig_02_06.jpg
Figure 6. FireBug Console

Select the Console option on the Firebug toolbar and enter alert("Hello from JavaScript") after the >>> sign and you’ll see the Alert box. To enter multi-line JavaScript code press the little circle with a caret at the bottom right corner and FireBug will open a panel on the right, where you can enter and run your JavaScript code.

This was probably the last example where we used the Alert() popup box for debugging purposes. All JavaScript debuggers support the console.log() for printing debug information. Consider the following example that illustrate strict equality operator ===. Yes, it’s three equal signs in a row. This operator evaluates to true if the values are equal and the data types are the same.

var age=25;

var ageStr="25";

if (age==ageStr){
  console.log("The values of age and ageStr are equal");
}

if (age===ageStr){
 console.log("The values of age and ageStr are strictly equal");
} else{
 console.log ("The values of age and ageStr are not strictly equal");
}

Running this code in the FireBug console produces the following output:

images/fig_02_07.jpg
Figure 7. Using console.log() for the debug output
Tip You can also use console.info(), console.debug(), and console.error() so the debuggers may highlight the output with different colors or mark with different icons.
Tip For more information about debugging JavaScript refer to the code samples illustrated in [FIG2-8] and [FIG2-9].

JavaScript Functions. Gentle Introduction

Now comes the chicken or the egg dilemma. What should be explained first - functions or objects? Understanding of objects is needed for some of the function code samples and visa versa. We’ll start with simple function use cases, but will be switching to objects as needed.

Many of the readers can have experience with object-oriented languages like Java or C#, where classes can include methods implementing required functionality. Then these methods can be invoked with or without instantiation of the objects. If a JavaScript object includes functions they are called methods. But JavaScript functions don’t have to belong to an object. You can just declare a function and invoke it. Just like this:

//Function declaration
function calcTax (income, dependents){
   var tax;
   // Do stuff here
   return tax;
}

//Function invocation
calcTax(50000, 2);
var myTax = calcTax(50000,2);

Please note that the data types of the function parameters income and dependents are not specified. We can only guess that they are numbers based on their names. If a software developer won’t bother giving meaningful names to function parameters, the code becomes difficult to read. After the function calcTax() is invoked and complete, the variable myTax will have the value returned by the function. In the above code sample the JavaScript engine will not evaluate the function calcTax() until it’s actually invoked.

Another important thing to notice is that our function has a name calcTax. But this is not always the case - JavaScript allows functions to be anonymous. If you see the line of code where the keyword function is preceded by any other character this is not a function declaration, but a function expression. Consider the following variation of the tax calculation sample:

//Function expression
var doTax=function (income, dependents){
        //do stuff here
   return tax;
}

//Function invocation
var myTax=doTax(50000,2);

In the code above the function keyword is being used in the expression - we assign the anonymous function to the variable doTax. After this assignment just the text of the function is assigned to the variable doTax - the anonymous function is not being invoked just yet. It’s important to understand that even though the code of this anonymous function ends with return tax; actually, the tax calculation and return of its value is not happening until the doTax() is invoked. Only then the function is evaluated and the variable myTax will get whatever value this function returns.

Yet another example of a function expression is when it’s placed inside the grouping operator - parentheses as shown below:

(function calcTax (income, dependents){
   // Do stuff here
});

Another interesting concept of JavaScript is self-executing functions. Adding an extra pair of parentheses will cause the function expression located in the first set of parentheses to be executed right away.

(function calcTax (income, dependents){
   // Do stuff here
})();

The first set of parentheses hides its internal code from the outside world creating a scope or a closed ecosystem, where the function’s code will operate. Try to add a line invoking this function after the last line in the above code sample, e.g. calcTax(50000,2), and you’ll get an error - "calcTax is not defined". There is a way to expose some of the internal content of such a closure and you’ll see how to do it later in this chapter.

JavaScript Objects. Gentle Introduction

JavaScript objects are simply unordered collections of properties. You can assign new or delete existing properties from the objects during the runtime whenever you please. In classical object oriented languages there are classes and there are objects. For example, based on one Java a class you can create multiple instances of its objects.

Note The ECMAScript 6 specification will include classes too, but since it’s a work in progress we won’t consider them as something useful in the today’s world. If you’d like to experiment with the upcoming features of JavaScript, download the Chrome Canary browser, go to chrome:flags and enable experimental JavaScript.

In JavaScript you can create objects using one of the following methods:

  • Using object literals

  • Using new Object() notation

  • Using Object.create()

  • Using constructor functions and a new operator.

Note In JavaScript everything is an Object. Think of Object as of a root of of the hierarchy of all objects used in your program. All your custom objects are descendants from Object.

Object Literals

The easiest way to create a JavaScript object is by using the object literal notation. The code sample below starts with a creation of an empty object. The second line creates an object with one property salary and assigns the value of 50000 to it. Finally, the instance of one more object pis created and the variable person points at it.

var t = {}             // create an instance of an empty object

var a = {salary: 50000}; // an instance with one property

// Store the data about Julia Roberts
var person = { lastName: ”Roberts”,
               firstName: ”Julia”,
                     age: 42
             };

This object has three properties: lastName, firstName, and age. Note that in object literal notation the values of these properties are specify using colon. You can access the properties of this person using the dot notation, e.g. person.LastName. But JavaScript allows yet another way of accessing the object properties by using square bracket syntax, for example person["lastName"]. In the next code sample you’ll see that using the square brackets is the only way to access the property.

 var person = {
       "last name": "Roberts",
       firstName: "Julia",
             age: 42};

var herName=person.lastName;          // 1

console.error("Hello " + herName);    // 2

herName=person["last name"];           // 3

person.salutation="Mrs. ";

console.log("Hello "+ person.salutation + person["last name"]); // 4
1 The object person doesn’t have a property lastName, but no error is thrown
2 This will print "Hello undefined"
3 Using and alternative way of referring to an object property
4 This will print "Hello Mrs. Roberts"
Tip It’s a good idea to keep handy a style guide of any programming language, and we know two of such documents for JavaScript. Google has published their version of JavaScript Style Guide at http://google-styleguide.googlecode.com/svn/trunk/javascriptguide.xml. A more detailed Airbnb JavaScript Style Guide is available as a github project at https://github.com/airbnb/javascript.

Objects can contain other objects. If a property of an object literal is also an object, you just need to specify the value of this property in an extra pair of curly braces. For example, you can represent the telephone of a person as an object having two properties: the type and the number. The following code snippet adds a nested object to store a work phone as a nested object inside the person’s object. Run this code in the FireBug’s console and it’ll print "Call Julia at work 212-555-1212".

var p = { lastName: "Roberts",
                firstName: "Julia",
                age: 42,
                phone:{
                      type: "work",
                      numb: "212-555-1212"
                 }
            };
console.log("Call " + p.firstName + " at " + p.phone.type + " " + p.phone.numb );

What if a person has more then one phone? We can change the name of the property phone to phones and instead store an array of objects. JavaScript arrays are surrounded by square brackets, and they are zero based. The following code snippet will print "Call Julia at home 718-211-8987".

var p = { lastName: "Roberts",
                firstName: "Julia",
                age: 42,
                phones:[{
                      type: "work",
                      numb: "212-555-1212"
                 },
                 {
                      type: "home",
                      numb: "799-211-8987"

                 }]
            };
console.log("Call " + p.firstName + " at " + p.phones[1].type + " " + p.phones[1].numb );
Methods in Object Literals

Functions defined inside objects are called methods. Defining methods in object literals is similar to defining properties - provide a method name followed by a colon and the function declaration. The code snippet below declares a method makeAppoyntment() to our object literal. Finally, the line p.makeAppointment(); invokes this new method, which will print the message on the console that Steven wants to see Julia and will call at so-and-so number.

var p = { lastName: "Roberts",
                firstName: "Julia",
                age: 42,
                phones:[{
                      type: "work",
                      numb: "212-555-1212"
                 },
                 {
                      type: "home",
                      numb: "718-211-8987"

                 }],
                makeAppointment: function(){
                    console.log("Steven wants to see  " + this.firstName +
                                 ". He'll call at " + this.phones[0].numb);
                }
            };

p.makeAppointment();
Note Since we already started using arrays, it’s worth mentioning that arrays can store any objects. You don’t have to declare the size of the array upfront and can create new arrays as easy as var myArray=[] or var myArray=new Array(). You can even store function declarations as regular strings, but they will be evaluated on the array initialization. For example, during the greetArray initialization the user will see a prompt asking to enter her name, and, when it’s done, the greetArray will store two strings. The output of the code fragment below can look like "Hello, Mary".
var greetArray=[
    "Hello",
    prompt("Enter your name", ”Type your name here")
];

console.log(greetArray.join(","));

We’ve briefly covered object literals, and you to start using them. In Chapter 4 you’ll be learning about JSON - a popular data format used as replacement for XML in the JavaScript world. Then you’ll see how similar are the syntax of JSON and JavaScript object literals. Now we’ll spend a little bit of time delving into JavaScript functions, and then - back to objects again.

Constructor Functions

JavaScript functions are more then just some named pieces of code that implements certain behavior. They also can become objects themselves by a magic of the new operator. To make things even more intriguing, the function calls can have memories, which will be explained in the section about closures.

If a function is meant to be instantiated with the new operator it’s called a constructor function. If you are familiar with Java or C# you understand the concept of a class constructor that is being executed only once during the instantiation of a class. Now imagine that there is only a constructor without any class declaration that still can be instantiated with the new operator as in the following example.


function Person(lname, fname, age){
         this.lastName=lname;
         this.firstName=fname;
         this.age=age;
};

// Creating 2 instances of Person
var p1 = new Person(“Roberts”,“Julia”, 42);

var p2 = new Person(“Smith”, “Steven”, 34);

This code declares the function Person and after that, it creates two instances of the Person objects referred by the variables p1 and p2 accordingly. This is what the statement functions are objects means.

Note According to common naming conventions the names of the constructor functions are capitalized.

Objects can have methods and properties, right? On the other hand, functions are objects. Hence functions can have methods and properties too. If you declare a function marryMe() inside the constructor function Person, marryMe() becomes a method of Person. This is exactly what we’ll do next. But this time we’ll create an HTML file that includes the <script> section referring to the JavaScript code sample located in a separate file.

If you want to try it hands-on, create a new file in your Aptana project by selecting the menu File | New | File and give it a name marryme.js. Agree with a suggested default JavaScript template, and key in the following content into this file:


function Person(lname, fname, age){
         this.lastName=lname;
         this.firstName=fname;
         this.age=age;

         this.marryMe=function(person){
                console.log("Will you marry me, " + person.firstName);
         };

};

var p1= new Person("Smith", "Steven");
var p2= new Person("Roberts", "Julia");

p1.marryMe(p2);

The code above uses the keyword this that refers to the object (a.k.a. context) where the code will execute. If you are familiar with the meaning of this in Java or C#, it’s similar, but not exactly the same, and we’ll illustrate it in the section titled "Who’s this". The method marryMe() of one Person object takes an instance of another Person object and makes an interesting proposition: "Will you marry me, Julia".

This time we won’t run this code in the Firebug’s console, but rather will include it in the HTML file. In Aptana, create a new File | New | File, enter marryme.html as the file name and press the button Finish. Don’t press the button Next as it’ll offer you to select from one of the HTML templates, but this would generate lots of HTML content, which is not needed for our code sample. Just type in the following in the newly created empty file marryme.html.

<!DOCTYPE html>
<html>
        <head>
                <meta charset="utf-8" />
        </head>

        <body>
                <h1>Making Proposal</h1>

                <script src="marryme.js"></script>
        </body>
</html>

Debugging JavaScript in Firebug

In Aptana, right-click on the file marryme.html and select the option Run As | JavaScript Web Application. We continue using Firefox as Aptana’s default browser, and you’ll see it open a new Web page that reads "Making Proposals". Open the Firebug using the View menu, refresh the page and switch to the Firebug’s tab Script. You’ll see the split panel with the JavaScript code from marryme.js on the left.

images/fig_02_08.jpg
Figure 8. Firebug’s Script panel

Let’s set a breakpoint inside the method marryMe() by clicking in the Firebug’s gray area to the left of the line 7. You’ll see a red circle that will reveal a yellow triangle as soon as your code execution will hit this line. Refresh the content of the browser to re-run the script with a breakpoint. Now the execution stopped at line 7, the right panel contains the runtime information about the objects and variables used by your program.

images/fig_02_09.jpg
Figure 9. Firebug’s Script panel at a breakpoint

On the top of the left panel you’ll see usual for debuggers curved arrows (Step Into, Step Over, Step Out) as well as triangular button to continue code execution. The right panel depicts the information related to this and global Window objects. In [FIG2-9] this represents the instance of the Person object represented by the variable p1 (Steven Smith). To see the content of the object, received by the method marryMe() you can add the watch variable by clicking on the text "New watch expression…" and entering person - the name of the parameter of marryMe(). [FIG2-10] shows the watch variable person (Julia Roberts) that was used during the invocation of the method marryMe().

images/fig_02_10.jpg
Figure 10. Firebug’s Script panel at a breakpoint

Now click on the Firebug’s Net panel, which shows what goes over the network during communication between the Web browser and Web server. Figure 2-11 shows a screen shot of the Net panel where we clicked on the Headers tab for marryme.html and the Response tab of marryme.js. The code 200 for both files means that they arrived successfully to the browser. It also shows the IP address of the Web server they came from, their sizes, and plenty of other useful information. Both Script and Net panels of Firebug or any other developers tools are your best friends of any Web developer.

images/fig_02_11.jpg
Figure 11. Firebug’s Net panel

We like Firebug, but testing and debugging should be done in several Web browsers. Besides Firebug, we’ll be using excellent Google Chrome developers tools. Their menus and panels are similar and we won’t be including such mini-tutorials on using such tools - you can easily learn them on your own.

Notes on Arrays

A JavaScript array is a grab bag of any objects. You don’t have to specify in advance the number of elements to store, and there is more than one way to create and initialize array instances. The following code samples are self-explanatory.


var myArray=[];
    myArray[0]="Mary";
    myArray[2]="John";

// prints undefined John
console.log(myArray[1] + " " + myArray[2]);

var states1 = ["NJ", "NY", "CT", "FL"];

var states = new Array(4);  // size is optional

states[0]="NJ";

states[1]="NY";

states[2]="CT";

states[3]="FL";

// remove one array element
delete states[1];


// prints undefined CT length=4
console.log(states[1] + " " + states[2] + " Array length=" + states.length);

// remove one element starting from index 2
states.splice(2,1);

// prints undefined  FL length=3
console.log(states[1] + " " + states[2] + " Array length=" + states.length);

Removing elements with delete creates gaps in the arrays while using the array’s method splice() allows to remove or replace the specified range of elements closing gaps.

The next code sample illustrates an interesting use case when we assign a string and a function text as array elements to mixedArray. During array initialization the function promt() will be invoked, the user will be prompted to enter name, and after that, two strings will be store in mixedArray, for example "Hello" and "Mary".


var mixedArray=[
    "Hello",
    prompt("Enter your name", ”Type your name here")
];

Prototypal Inheritance

JavaScript doesn’t support classes, at least till the ECMAScript 6 will become a reality. But JavaScript allows you to create objects that inherit properties and methods of other objects. By default, all JavaScript objects are inherited from Object. Each JavaScript construction function has a special property called prototype, which points at this object’s ancestor. If you want to create an inheritance chain where an instances of constructor function ObjectB extend ObjectA just write one line of code: ObjectB.prototype=ObjectA;.

images/fig_02_12.jpg
Figure 12. Prototypal Inheritance

Consider two constructor functions Employee and Person shown in the code snippet below.They represent two unrelated objects. But assigning the Person object to the prototype property of Employee creates an inheritance chain, and now the object emp will have all properties defined in both Employee and Person.


function Person(name, title){
        this.name=name;
        this.title=title;
        this.subordinates=[];
}

function Employee(name, title){
        this.name=name;
        this.title=title;
}

// All instances of Employee will extend Person
Employee.prototype = new Person();            // 1

var emp=new Employee("Mary", "Specialist"); // 2

console.log(emp);      // 3
1 Assigning an ancestor of type person
2 Instantiating Employee
3 Printing the object referred by emp will output [object Object]. It happens because each object has a method toString(), and if you want it to output useful information - override it. You’ll see how to do it later in this section.

We want to stress, that the property prototype exists on constructor functions. After creating specific instances of such objects you may see that these instances have another property called proto. At the time of this writing this property is not a standard yet and won’t be supported in some older browsers, bit ECMAScript 6 will make it official. To illustrate the difference between prototype and proto let’s add the following piece of code to the above sample:


//Create an instance of Person and add property dependents
var p=new Person();
p.dependents=1;                                 // 1


var emp2=new Employee("Joe", "Father");

//This employee will have property dependents

emp2.__proto__=p;                               // 2

console.log("The number of Employee's dependents " + emp2.dependents); // 3
1 Creating an instance of Person and adding an extra property dependents just for this instance
2 Assigning this instance to the __proto__ property of one instance
3 The code will properly print 1 as a number of dependents of the Employee instance represented by the variable emp2. The variable emp from the previous code snippet won’t have the property dependents.

To try it hands-on, open the file WhoIsYourDaddy.html in Aptana. Just for a change, this time we’ll use Google Chrome Developer Tools by opening the menu View | Developer | Developer Tools. Set the breakpoint at the last line of the JavaScript, refresh the Web page content, and add the watch expressions for the variables p, emp, and emp2. When the JavaScript code engine runs into emp2.dependents it tries to find this property in property on the Employee object. If not found, the engine checks all the objects in the prototypal chain (in our case it’ll find it in the object p) all the way up to the Object if need be.

Tip If you need to do some programmatic manipulations with only those properties that are defined on the specific object (not in its ancestors) do the check with the method hasOwnProperty().
images/fig_02_13.jpg
Figure 13. The instance-specific __proto__ variable
Tip You can find a tutorial on using Google Chrome Developer Tools at https://developers.google.com/chrome-developer-tools/. The cheatsheet of Chrome developer Tools is located at http://anti-code.com/devtools-cheatsheet/.

Please not the difference in the content of the variables __proto__ of the instances represented by emp and emp2. These two employees are inherited from two differnet objects Person. Isn’t it scary? Not really.

Where to Declare Methods

If you take a closer look at the screenshot from [FIG2-13] you’ll see that the Person and Employee objects have redundant properties name and title. We’ll deal with this redundancy in the section titled "Call and Apply". But first let’s introduce and cure the redundancy in method declarations when the prototypal inheritance is used.

Let’s add a method to addSubordinate() to the ancestor object Person that will populate its array subordinates. Who knows, maybe an object Contractor (descendant of a Person) will need to be added in the future, so the ancestor’s method addSubordinate() can be reused. First, we’ll do it the wrong way to illustrate the redundancy problem, and then we’ll do it right. Consider the following code:

// Constructor function Person
function Person(name, title){
        this.name=name;
        this.title=title;
        this.subordinates=[];

    // Declaring method inside the constructor function
        this.addSubordinate=function (person){
                this.subordinates.push(person)
        }


}

// Constructor function Employee
function Employee(name, title){
        this.name=name;
        this.title=title;
}

// Changing the inheritance of Employee
Employee.prototype = new Person();

var mgr =  new Person("Alex", "Director");
var emp1 = new Employee("Mary", "Specialist");
var emp2 = new Employee("Joe", "VP");

mgr.addSubordinate(emp1);
mgr.addSubordinate(emp2);
console.log("mgr.subordinates.length is " + mgr.subordinates.length);

The method addSubordinate() here is declared inside the constructor function Person, which becomes an ancestor of the Employee. After instantiation of two Employee objects the method addSubordinate() is duplicated for each instance.

Let’s use Google Chrome Developer Tools profiler to see the sizes of the objects allocated on the Heap memory. But first we’ll set up two breakpoints - one before, and one after creating our instances as shown on [FIG2-14].

images/fig_02_14.jpg
Figure 14. Preparing Breakpoints Take 1.

When the execution of the code will stop at the first breakpoint, we’ll switch to the Profiler tab and take the first Heap snapshot. Upon reaching the second breakpoint we’ll take another Heap snapshot. The dropdown at the status bar allows to view the objects allocated between the snapshots 1 and 2. [FIG2-15] depicts this view of the profiler. Note that the total size (the Shallow Size column) for the Person instances is 132 bytes. Employee instances weigh 104 bytes.

images/fig_02_15.jpg
Figure 15. Objects allocated between snapshots 1 and 2

Now we’ll change the code to declare the method not inside the Person constructor function, but on it’s prototype - and this is the right way to declare methods in functions to avoid code duplication.

// Constructor function Person
function Person(name, title){
        this.name=name;
        this.title=title;
        this.subordinates=[];

}

//Declaring method on the object prototype
Person.prototype.addSubordinate=function(subordinate){
   this.subordinates.push(subordinate);
   return subordinate;
}

// Constructor function Employee
function Employee(name, title){
        this.name=name;
        this.title=title;
}

// Changing the inheritance of Employee
Employee.prototype = new Person();

var mgr =  new Person("Alex", "Director");
var emp1 = new Employee("Mary", "Specialist");
var emp2 = new Employee("Joe", "VP");

mgr.addSubordinate(emp1);
mgr.addSubordinate(emp2);
console.log("mgr.subordinates.length is " + mgr.subordinates.length);

Similarly, we’ll set up two breakpoints before and after object instantiation as shown in <<>FIG2-16>.

images/fig_02_16.jpg
Figure 16. Preparing Breakpoints Take 2.

Let’s take two more profiler snapshots upon reaching each of the breakpoint. While the weight of the Employee instances remained the same (104 bytes), the Person instances became lighter: 112 bytes. While 20 bytes may not seem like a big deal, if you’ll need to create hundreds or thousands of object instances it adds up.

images/fig_02_17.jpg
Figure 17. Objects allocated between snapshots 3 and 4

So if you need to declare a method on the object that will play a role of the ancestor, do it on the prototype level. The only exception to this rule is the case when such method needs to use some object specific variable that’s different for each instance - in case declare methods inside the constructors (see the section on closures for details).

Note All modern Web browsers support the function Object.create(), which creates a new object based on another prototype object. For example, var objectB=Object.create(objectA);. What if you must support an older browser and need such "create by example" functionality? Of course, you can always create a custom arbitrarily named function with the similar functionality as the latest implementation of Object.create(). But the future-proof approach is to create the missing methods with the same signatures and on the same objects as the latest ECMAScript specification prescribes. In case of Object.create() you can use the implementation offered by Douglas Crockford:
if (typeof Object.create !== 'function') {
    Object.create = function (o) {
        function F() {}
        F.prototype = o;
        return new F();
    };
}
newObject = Object.create(oldObject);

Such approach of custom implementation of missing pieces according to the latest ECMAScript specifications or W3C drafts is known as polyfills. People who can’t wait till the browser vendors will implement the newest functionality create cross-browser polyfills and some of them submit their source code to the public domain. You can find a number of polyfills in the git repository of the Modernizr project. The Web site http://caniuse.com/ contains the current information about browser’s support of the latest HTML5, JavaScript, and CSS features.

Method overriding

Since JavaScript allows declaring methods on an object as well as on its prototype, overriding a method becomes really simple. The following code sample declares the method addSubordinate() on the prototype of the Person object, but then the object p1 overrides this method.

function Person(name, title){

  this.name=name;
  this.title=title;
  this.subordinates=[];
}

Person.prototype.addSubordinate=function(person){

   this.subordinates.push(person);
   console.log("I'm in addSubordinate on prototype " + this);
}

var p1=new Person("Joe", "President");

    p1.addSubordinate=function(person){

    this.subordinates.push(person);
    console.log("I'm in addSubordinate in object " + this);
  }

var p2 = new Person("Mary", "Manager")

    p1.addSubordinate(p2);

Running the above code prints only one line: "I’m in addSubordinate in object [object Object]". This proves that the method addSubordinate() on the prototype level is overridden. We can also improve this example a little bit and override the method toString() on the Person. Just add the following fragment to the prior to instantiating p1.

Person.prototype.toString=function(){
   return "name:" + this.name +" title:" + this.title;
}

Now the code prints "I’m in addSubordinate in object name:Joe, title:President". Overriding the method toString() on objects is a common practice as it gives a textual representation of your objects.

Scope or who’s this?

You are about to read one of the most confusing sections in this book. The confusion is caused by some inconsistencies in JavaScript design and implementations by various browsers. Do you know what will happen if you’ll remove the keywords this from the toString() method from previous section? You’ll get an error - the variable title is not defined. Without the keyword this the JavaScript engine tries to find the variable title in the global namespace. Declaring and initializing the variable title outside of the Person declaration get rid of this error, but this is not what we want to do. Misunderstanding of the current scope can lead to difficult to debug errors.

Caution Interestingly enough replacing this.name with name doesn’t generate an error, but rather initializes the variable name with an empty string. Although name is not an officially reserved JavaScript keyword, there are articles in the blogosphere that don’t recommend using the word name as a variable name. Keep this list of reserved words handy to avoid running into an unpredictable behavior.

Let’s consider several examples that will illustrate the meaning of this variable in JavaScript. The code sample below defines an object myTaxObject and calls its method doTaxes(). Notice two variables with the same name taxDeduction - one of them has global scope and another belongs to myTaxObject. This little program was written for mafia and will apply some under the table deduction for the people who belong to Cosa Nostra.

var taxDeduction=300;      // global variable

var myTaxObject = {

    taxDeduction: 400,    // object property

    doTaxes: function() {
         this.taxDeduction += 100;

         var mafiaSpecial= function(){
           console.log( "Will deduct " + this.taxDeduction);
         }

         mafiaSpecial();  // invoking as a function
    }
}

myTaxObject.doTaxes();  //invoking method doTaxes

This code fragment illustrates the use of nested functions. The object method doTaxes() has a nested function mafiaSpecial(), which is not visible from outside of the myTaxObject, but it can be certainly invoked inside doTaxes(). What number do you think this code will print after the words "Will deduct "? Will it print three, four, or five hundred? Run this code in Firebug, Chrome Developer Tools or any other way and you’ll see that it’ll print 300!

But this doesn’t sound right, does it? The problem is that in JavaScript the context where the function executes depends on the way it was invoked. In this case the function mafiaSpecial() was invoked as a function (not a method) without specifying the object it should apply to, and JavaScript makes it operate in the global object, hence the global variable taxDeduction having the value of 300 is being used. So in expression this.taxDeduction the variable this means global unless the code is operated in the strict mode.

Note ECMAScript 5 introduced a restricted version of JavaScript called strict mode, which among other things places stricter requirements to variable declarations and scope identification. Adding "use strict" as the first statement of the method doTax() will make the context undefined, and it’ll print the error "this is undefined" and not 300. You can read about the strict mode at Mozilla’s developers site.

Let’s make a slight change to this example and take to control what this represents. When the object myTaxObject was instantiated its own this reference was created. The following code fragment stores this reference in additional variable thisOfMyTaxObject changes the game and the expression thisOfMyTaxObject.taxDeduction evaluates to 500.

var taxDeduction=300;      // global variable

var myTaxObject = {

    taxDeduction: 400,    // object property

    doTaxes: function() {
    var thisOfMyTaxObject=this;
         this.taxDeduction += 100;

         var mafiaSpecial= function(){
           console.log( "Will deduct " + thisOfMyTaxObject.taxDeduction);
         }

         mafiaSpecial();  // invoking as a function
    }
}

myTaxObject.doTaxes();  //invoking method doTaxes

You’ll see a different way of running a function in the context of the specified object using special functions call() and apply(). But for now consider one more attempt to invoke mafiaSpecial()`shown in the following example that uses `this.mafiaSpecial() notation.

var taxDeduction=300;      // global variable

var myTaxObject = {

    taxDeduction: 400,    // object property

    doTaxes: function() {
         this.taxDeduction += 100;

         var mafiaSpecial= function(){
           console.log( "Will deduct " + this.taxDeduction);
         }

         this.mafiaSpecial();  // trying to apply object's scope
    }
}

myTaxObject.doTaxes();  //invoking method doTaxes

Run the above code and it’ll give you the error "TypeError: this.mafiaSpecial is not a function" and rightly so. Take a closer look at the object myTaxObject represented by the variable this. The myTaxObject has only two properties: taxDeduction and doTaxes. The function mafiaSpecial is hidden inside the method doTaxes and can’t be accessed via this.

Call and Apply

Visualize the International Space Station, and add to the picture an image of a approaching space shuttle. After attaching to the docking bay of the station the shuttle’s crew performs some functions on the station (a.k.a. object) and then flies to another object or back to Earth. What is has to do with JavaScript? It can serve as an analogy for creating a JavaScript function that can operate in the scope of any arbitrary object. For this purpose JavaScript offers two special functions: call() or apply(). Both call() and apply() can invoke any function on any object. The only difference between them is that apply() passes required parameters to a function as an array, while call() uses a comma-separated list.

Tip Every function in JavaScript is a Function object. Both call() and apply() are defined in the Function object.

For example, a function calcStudentDeduction(income,numOfStudents) can be invoked in a context of a given object using either call() or apply(). Note that with call() parameters have to be listed explicitly, while with apply parameters are given as an array:

calcStudentDeduction.call(myTaxObject, 50000, 2);

calcStudentDeduction.apply(myTaxObject, [50000, 2]);

In the above example the instance of ‘myTaxObject` can be referred as this from within the function calcStudentDeduction() even though this is a function and not a method. The last example from the previous section can be re-written to invoke mafiaSpecial(). The following code will ensure that mafiaSpecial() has this pointing to `myTaxObject’ and will print on the console "Will deduct 500".

var taxDeduction=300;      // global variable

var myTaxObject = {

    taxDeduction: 400,

    doTaxes: function() {
         this.taxDeduction += 100;

         var mafiaSpecial= function(){
           console.log( "Will deduct " + this.taxDeduction);
         }

         mafiaSpecial.call(this);  // passing context to a function
    }
}

myTaxObject.doTaxes();

Callbacks

Can you live without using call() and apply()? Sure you can, but in JavaScript can easily create callbacks - you can pass the code of one function as a parameter to another function for execution in the latter function’s context. Most likely you’ve seen how event handlers are declared. If a user clicks on this button here’s the name of the handler function to call: myButton.addEventListener("click", myFunctionHandler)

It’s important to understand that you don’t not immediately call the function myFunctionHandler here - you are just registering it. If and only if the user will click on myButton then the callback myFunctionHandler has to be invoked in the context of the myButton object. The functions call() and apply() exist exactly for this purpose.

Let’s consider an example when you need to write a function that will take two arguments - and array with preliminary tax data and a callback function to be applied to each element of this array. The following code sample creates myTaxObject that has two properties: taxDeduction and the applyDeduction. The latter is a method with two parameters: array and a callback to be applied to this array.

var myTaxObject = {

    taxDeduction: 400, // state-specific  deduction

    // this function takes an array and callback as parameters
    applyDeduction: function(someArray, someCallBackFunction){

        for (var i = 0; i < someArray.length; i++){

            // Invoke the callback
           someCallBackFunction.call(this, someArray[i]);
        }

    }
}

// array
var preliminaryTaxes=[1000, 2000, 3000];

// tax handler function
var taxHandler=function(currentTax){
                   console.log("Hello from callback. Your final tax is " +
                   (currentTax - this.taxDeduction));
                }

// invoking applyDeduction passing an array and callback
myTaxObject.applyDeduction(preliminaryTaxes, taxHandler);

The above code invokes applyDeduction() passing it the array preliminaryTaxes and the callback function taxHandler that takes the currentTax and subtracts this.taxDeduction. By the time this callback will be applied to each element of the array the value of this will be known and this code will print the following:

Hello from callback. Your final tax is 600
Hello from callback. Your final tax is 1600
Hello from callback. Your final tax is 2600

You may be wondering, why passing the function to another object if we could take an array, subtract 400 from each of its elements and be done with it? The solution with callbacks gives you an ability to make the decision on what function to call during the runtime and call it only when a certain event happens. Callbacks allow you to do asynchronous processing. For example, you make an asynchronous request to a server and register the callback to be invoked if a result comes back. The code is not blocked and doesn’t wait until the server response is ready. Here’s an example from AJAX: request.onreadystatechange=myHandler. You register myHandler callback but not immediately call it. JavaScript functions are objects, so get used to the fact that you can pass them around as you’d be passing any objects.

Hoisting

A variable scope depends on where it was declared. You already had a chance to see that a variable declared inside a function with the keyword var is visible only inside this function. Some programming languages allow to narrow down the scope even further. For example, in Java declaring a variable inside any block of code surrounded with curly braces makes it visible only inside such a block. In JavaScript it works differently. No matter where in the function you declared the variable its declaration will be hoisted to the top of the function, and you can use this variable anywhere inside the function.

The following code snippet will print 5 even though the variable b has been declared inside the if-statement. It’s declaration has been hoisted to the top:

function test () {
    var a=1;

    if(a>0) {
        var b = 5;
    }
    console.log(b);

}

test();

Let’s make a slight change to the above code to separate the variable declaration and initialization. The following code has to console.log(b) statements. The first one will output undefined and the second will print 5 just as in the previous example.

function test () {
    var a=1;

    console.log(b);  // b is visible, but not initialized

    if(a>0) {
        var b;
    }

    b=5;

    console.log(b);  // b is visible and initialized
}

test();

Due to hoisting, JavaScript doesn’t complain when the first console.log(b) is invoked. It knows about the variable b, but its value is undefined just yet. By the time the second console.log(b) is called, the variable b was initialized with the value of 5. Just remember that hoisting just applies to variable declaration and doesn’t interferes with your code when it comes to initialization. JavaScript function declarations are hoisted too, and this is illustrated in the following code sample.

function test () {
    var a=1;

    if(a>0) {
        var b;
    }

    b=5;

    printB();

    function printB(){
        console.log(b);
    }
}

test();

This code will print 5. We can call the function printB() here because its declaration was hoisted to the top. But the situation changes if instead of function declaration we’ll use the function expression. The following code will give you an error "PrintB is not a function". Notice that it the error doesn’t complain about printB being undefined cause the variable declaration was hoisted, but since the function expression wasn’t the JavaScript engine doesn’t know yet that printB will become a function really soon. Anyway, moving the invocation line printB() to the bottom of the function test() cures this issue. Function expressions are not being hoisted.

function test () {
    var a=1;

    if(a>0) {
        var b;
    }

    b=5;

    printB();

    var printB = function(){
        console.log(b);
    }

}

test();

All code samples in this section first declare the function test() and then invoke it. This function test() is being called once and there is no reason to give it a name. Using so called self-invoked function notation allows to declare and automatically invoke the function (note the extra parentheses at the end of the following code).

(function () {
    var a=1;

    if(a>0) {
        var b;
    }

    b=5;

    printB();

    var printB = function(){
        console.log(b);
    }

})();

Function properties

Functions as any other objects can have properties. You can attach any properties to a Function object and their values can be used by all instances of this object. Static variables in programming languages with the classical inheritance is the closest analogy to function properties in JavaScript.

Let’s consider an example of a constructor function Tax. An accounting program can create multiple instances if Tax - one per person. Say this program will be used in a Florida neighborhood with predominantly Spanish speaking people. The following code illustrates the case when the method doTax() can be called with or without parameters.

function Tax(income, dependents){
    this.income=income;              // instance variable
    this.dependents=dependents;      // instance variable

    this.doTax = function calcTax(state, language){
           if(!(state && language)){     // 1
              console.log("Income: " + this.income + " Dependents: "+ this.dependents
              + " State: " + Tax.defaults.state + " language:" + Tax.defaults.language);
           } else{                       // 2
              console.log("Income: " + this.income + " Dependents: "+ this.dependents
              + " State: " + state + " language:" + language);
           }
    }
}

Tax.defaults={                           // 3
     state:"FL",
     language:"Spanish"
};

// Creating 2 Tax objects
var t1 = new Tax(50000, 3);
    t1.doTax();                          // 4
var t2 = new Tax(68000, 1);
    t2.doTax("NY","English");            // 5
1 No state and language were given to the method doTax()
2 The state and language were provided as doTax() parameters
3 Assigning the object with two properties as a defaults property on Tax. The property default is not instance specific, which makes it static.
4 Invoking doTax() without parameters - use defaults
5 Invoking doTax() with parameters

This program will produce the following output:

Income: 50000 Dependents: 3 State: FL language:Spanish
Income: 68000 Dependents: 1 State: NY language:English

You can add as many properties to the constructor function as needed. For example, to count the number of instances of the Tax object just add one more property Tax.counter=0;. Now add to the Tax function something like console.log(Tax.counter++); and you’ll see that the counter increments on each instance creation.

Tip If multiple instances of a function object need to access certain HTML elements of the DOM, add references to these elements as function properties so objects can reuse them instead of traversing the DOM (it’s slow) from each instance.

Closures

Imagine a function that contains a private variable, and a nested function. Is it possible to invoke the nested function from the outside of the outer one? And if it’s possible, what this inner function knows about its surroundings?

Larry Ullman, a Web developer and computer books author offers the following definition: "Closure is a function call with memory". We can offer you our version: "Closure is a function call with strings attached". Now it’s turn for the explanation of these mysterious definitions, and we’ll do it by example. Consider the following code that is yet another example of implementing tax collection functionality.

(function (){                // this is an anonymous function expression

    var taxDeduction = 500;  // private context to remember

      //exposed closure
      this.doTaxes=function(income, customerName) {

        var yourTax;

        if (customerName != "Tony Soprano"){
          yourTax =   income*0.05 - taxDeduction;
        } else{
          yourTax =   mafiaSpecial(income);
        }

         console.log( "   Dear " + customerName + ", your tax is "+ yourTax);
         return yourTax;
      }

      //private function
      function mafiaSpecial(income){
          return income*0.05 - taxDeduction*2;
      }

})();    // Self-invoked function

// The closure remembers its context with taxDeduction=500
doTaxes(100000, "John Smith");
doTaxes(100000, "Tony Soprano");

mafiaSpecial();        // throws an error - this function is private

First, a self-invoking function will create an anonymous instance of an object in the global scope. It contains a private variable taxDeduction, a public method doTaxes(), and a private method mafiaSpecial(). Just by the virtue of declaring doTaxes on this object, this method becomes exposed to the current scope, which is global in this example.

After that we call the method doTaxes() twice. Note that the function doTaxes() uses the variable taxDeduction that was never declared there. But when doTaxes was initially declared, the variable taxDeduction with a value of 500 was already there. So the internal function "remembers" the context (the neighborhood) where it was declared and can use it for its calculations.

The algorithm of tax calculations makes doTaxes() calls the function mafiaSpecial() if the customer’s name is "Tony Soprano". The function mafiaSpecial() is not visible from outside, but for insiders like doTaxes() it’s available. Here’s what the above code example will print on the console:

Dear John Smith, your tax is 4500
Dear Tony Soprano, your tax is 4000
Uncaught ReferenceError: mafiaSpecial is not defined

The [FIG2-18] shows the screenshot taken when doTaxes() hit the breakpoint inside doTaxes - note the right panel that shows what’s visible in the Closure scope.

images/fig_02_18.jpg
Figure 18. Closure view in Chrome’s Developer Tools.
Tip JavaScript doesn’t give you an explicit way to mark an variable as private. By using closures you can get the same level of data hiding that you get from private variables in other languages. In the example above the variable taxDeduction is local for the object enclosed in the outermost parentheses and can’t be accessed from outside. But taxDeduction can be visible from the object’s functions doTaxws and mafiaSpecial.

[FIG2-19] gives yet another visual representation of our above code sample. The self-invoked anonymous function is shown as a cloud that exposes only one thing to the rest of the world: the closure doTaxes.

images/fig_02_19.jpg
Figure 19. Closure doTaxes

Let’s consider a couple of more cases of returning a closure to the outside world so it can be invoked later. If the previous code sample was exposing the closure by using this.taxes notation, the next two examples will simply return the code of the closure using the return statement. The code below declares a constructor function Person, adds a function doTaxes() to its prototype, and finally creates two instances of the Person calling the method doTaxes() on each of them.

// Constructor function
function Person(name){

        this.name = name;

}

// Declaring a method that returns closure
Person.prototype.doTaxes= function(){

    var taxDeduction = 500;

      //private function
      function mafiaSpecial(income){
          return income*0.05 - taxDeduction*2;
      }

      //the code of this function is returned to the caller
      return function(income) {

        var yourTax;

        if (this.name != "Tony Soprano"){
          yourTax =   income*0.05 - taxDeduction;
        } else{
          yourTax =   mafiaSpecial(income);
        }

         console.log( "My dear " + this.name + ", your tax is "+ yourTax);
         return yourTax;
      }
}();     // important parentheses!

//Using closure
var p1 = new Person("John Smith");
var result1 = p1.doTaxes(100000);

var p2 = new Person("Tony Soprano");
var result2 = p2.doTaxes(100000);

The calculated taxes in this example are the same as in the previous one: John Smith has to pay $4500, while Tony Soprano only $4000. But we used different technique for exposing the closure. We want to make sure that you didn’t overlooked the parentheses at the very end of the function expression for doTaxes. These parenthesis force the anonymous function to self-invoke itself, it’ll run into a return statement and will assign the code of the anonymous inner function that takes parameter income to the property doTaxes. So when the line var result1 = p1.doTaxes(100000); calls the closure the variable result1 will have the value 4500. Remove these important parentheses, and the value of result1 is not the tax amount, but the the code of the closure itself - the invocation of the closure is not happening.

The following code fragment is yet another example of returning the closure that remembers its context.First, the closure is returned to the caller of prepareTaxes(), and when the closure will be invoked it’ll remember the values defined in its outer context. After looking at this code you can say that there is nothing declared in the closure’s outside context! There is - by the time when the closure is created the value of the studentDeductionAmount will be known.

function prepareTaxes(studentDeductionAmount) {

        return function (income) {           // 1
           return income*0.05 - studentDeductionAmount;
        };

}

var doTaxes = prepareTaxes(300);         // 2
var yourTaxIs = doTaxes(10000);          // 3
console.log("You tax is " + yourTaxIs);  // 4
1 When the function prepareTaxes is called, it immediately hits the return statement and returns the code of the closure to the caller.
2 After this line is executed, the variable doTaxes has the code of the closure, which remembers that studentDeductionAmount is equal to 300.
3 This is actual invocation of the closure
4 the console output is "your tax is 200"

Closures as callbacks

Let’s revisit the code from the section Callbacks above. That code has shown how to pass an arbitrary function to another one and invoke it there using call(). But if that version of the function taxHandler was not aware of the context it was created in, the version below will. If in classical object-oriented languages you’d need to pass a method that knows about it’s context, you’d need to create an instance of an object that contains the method and the required object-level properties, and then you’d be passing this wrapper-object to another object for processing. But since the closure remembers its context anyway, we can just pass a closure instead of object. Compare the code below with the code from the Callbacks section.

var myTaxObject = {

    // this function takes an array and callback as parameters
    applyDeduction: function(someArray, someCallBackFunction){

        for (var i = 0; i < someArray.length; i++){

            // Invoke the callback
           someCallBackFunction.call(this, someArray[i]);
        }

    }
}

// array
var preliminaryTaxes=[1000, 2000, 3000];


var taxHandler = function (taxDeduction){

// tax handler closure
        return function(currentTax){
                   console.log("Hello from callback. Your final tax is " +
                   (currentTax - taxDeduction));
                };
}


// invoking applyDeduction passing an array and callback-closure
myTaxObject.applyDeduction(preliminaryTaxes, taxHandler(200));

The last line of the above example calls taxHandler(200), which creates a closure that’s being passed as a callback to the method applyDeduction(). Even though this closure is executed in the context of myTaxObject, it remembers that tax deduction is 200.

Mixins

The need to extend capabilities of objects can be fulfilled by inheritance, but this is not the only way of adding behavior to objects. In this section you’ll see an example of something that would not be possible in the object-oriented languages like Java or C#, which don’t support multiple inheritance. JavaScript allows taking a piece of code and mix it into any object regardless of what its inheritance chain is. Mixin is a code fragment that an object can borrow if need be.

// Defining a function expession
var Tax = function(income, state){
        this.income=income;
        this.state=state;

        this.calcTax=function(){
                var tax=income*0.05;
                console.log("Your calculated tax is " + tax)
                return tax;
        }
};


// Defining a mixin
var TaxMixin = function () {};

TaxMixin.prototype = {

  mafiaSpecial: function(originalTax){
    console.log("Mafia special:" + (originalTax - 1000));
  },

  drugCartelSpecial: function(originalTax){
     console.log("Drug Cartel special:" + (originalTax - 3000));
  }

};

// this function can blend TaxMixin into tax
function blend( mainDish, spices ) {

  for ( var methodName in spices.prototype ) {
      mainDish.prototype[methodName] = spices.prototype[methodName];
  }
}

// Blend the spices with the main dish
blend( Tax, TaxMixin );

// Create an instant of Tax
var t = new Tax(50000, "NY");

var rawTax = t.calcTax();

// invoke a freshly blended method
t.mafiaSpecial(rawTax);

The function blend() loops through the code of the TaxMixin and copies all its properties into Tax. Mixins can be useful is you want to provide a specific feature to a number of different object without changing their inheritance. The other use case is if you want to prepare a bunch of small code fragments (spices) and add any combination of them to the various objects (dishes) as needed. Mixins give you a lot of flexibility in what you can achieve with the minimum code, but they may decrease the readability of your code.

If you’ve read this far, you should have a good understanding of the syntax of the JavaScript language.Studying the code samples provided in this chapter has one extra benefit: now you can apply for a job as a tax accountant in a mafia near you.

JavaScript in the Web Browser

After learning all these facts and techniques about the language you might be eager to see "the real-world use of JavaScript". Slowly but surely a Web browser becomes the leading platform for development of the user interface. The vast majority today’s JavaScript programs primarily manipulate HTML elements of Web pages. In this section we’ll be doing exactly this – applying JavaScript code to modify the content or style of HTML elements.

DOM stands for Document Object Model. It’s an object representing the hierarchy of HTML elements of a Web page. Every element of the HTML document is loaded into DOM. Each DOM element has a reference to its children and siblings. When DOM was invented, the Web pages were simple and static. DOM was not meant to be an object actively accessed by the code. This is the reason that on some of the heavily populated Web pages manipulating of DOM elements can be slow. Most likely DOM is the main target for anyone who’s trying to optimize the performance of a Web page.

Tip If your Web page is slow, analyze it with YSlow, the tool built based on the Yahoo! rules for high performance Web sites.

When a Web Browser is receiving the content it keeps performing the following activities:

  • Adding arriving HTML elements to DOM and laying out the content of the Web pages

  • Rendering of the UI

  • Running JavaScript that was included in the HTML

  • Processing events

The amount of time spent on each of these activities varies depending the content of the page.

Tip If you are interested in learning how the browsers work in detail, read an excellent writeup titled "How Browsers Work: Behind The Scenes of Modern Web Browsers" at http://bit.ly/how-browsers-work [http://bit.ly/how-browsers-work].

Let’s consider the operations your application needs to be able to perform inside the Web page:

  • Programmatically finding the required element by id, type, or a CSS class

  • Changing styles of the elements (show, hide, apply fonts and colors et al.)

  • Processing events that may happen to HTML elements (click, mouseover and the like)

  • Dynamically adding or removing HTML elements from the page or changing their contents

  • Communicating with the server side, e.g. submitting forms or making AJAX requests for some data from the server

Now you’ll see some code samples illustrating the use of JavaScript for the listed above operations. Even if you’ll be using one of the popular JavaScript frameworks, your program will be performing similar operations applying the syntax prescribed by your framework of choice. So let’s learn how it can be done.

Working with DOM

If you want to change the appearance of an HTML page, you need to manipulate with the DOM elements. Older Web applications were preparing the HTML content on the server side. For example, a server-side Java servlet would compose and send to the client HTML whenever the application logic required to change the appearance of the UI. The current trend is different - the client’s code takes care of the UI rendering, and only the data go back and forth between the client and the server. You’ll see how this works in more detail in Chapter 4 that explains the use of AJAX and JSON.

Earlier in this chapter we were talking about the global namespace where all JavaScript objects live unless they were declared with var inside the functions. If the JavaScript code is running in a Web browser, this global namespace is represented by a special variable window. It’s an implicit variable and you don’t have to use it in your code, but whenever we say that a variable is global, we mean that it’s exists on the window object. For example, the code below will print "123 Main Street" twice:

var address ="123 Main Street";

console.log(address);
console.log(window.address);

The window object has a number of useful properties like cookie, location, parent, document and others. The variable document points at the root of the DOM hierarchy. Pretty often your JavaScript code would find an element in the DOM first, and then it could read or modify its content. [FIG2-20] is a snapshot from Firebug showing the fragment of a DOM of a simple Web page mixins.html.

images/fig_02_20.jpg
Figure 20. Firebug’s representation of DOM
Single Page Applications

Have you ever seen a monitor of a trader working for a Wall Street firm? Actually, they usually have three or four large monitors, but let’s just look at one of them. Imagine a busy screen with lots and lots constantly changing data grouped in dedicated areas of the window. This screen shows the constantly changing prices from financial markets, the trader can place orders to buy or sell products, and notifications on completed trades are also coming to the same screen. If this is would be a Web application it would live in the same Web page. No menus to open another windows.

The price of Apple share was $590.45 just a second ago and now it’s $590.60. How can this be done technically? Here’s one of the possibilities: every second an AJAX is being made to the remote server providing current stock prices and the JavaScript code finds in the DOM the HTML element responsible for rendering the price and then modifies its value with the latest price.

Have you seen a Web page showing an input box of Google’s Gmail? It looks like a table with a list of rows representing the sender, subject, and the date of when each email arrived. All of a sudden you see a new row in bold on top of the list - the new email came in. How was this done technically? A new object(s) was created and inserted into a DOM tree. No page changes, no needs for the user to refresh the browser’s page - an undercover AJAX call gets the data and JavaScript changes the DOM. The content of DOM changed - the user sees an updated value.

Below are some of the methods that exist on the `document` object:

document.write(text) – adds the specifies text to the DOM. Careless using of the method write() can result in unpredictable results if after changing the DOM the HTML content is still arriving.

document.getElementById(id) – get a reference to the HTML element by its unique identifier

document.getElementsByTagName(tname) - get a reference to one or more elements by tag names, e.g.get a reference to all <div> elements.

document.getElementsByName(name) - get a reference to all elements that have requested value in their name attribute.

document.getElementsByClassName(className) – get a reference to all elements to use specified CSS class.

document.querySelector(cssSelector) – Find the first element that matches provided CSS selector. string.

document.querySelectorAll(cssSelector) – Find all elements that match provided CSS selector string.

The next code sample contains the HTML <span> element that has an id emp. Initially it contains ellipsis, but when the user enters the name in the input text field, the JavaScript code will find the reference to this <span> element and will replace the ellipsis with the content of the input text field.

<!DOCTYPE html>
<html>
        <head>
                <meta charset="utf-8" />
        </head>

        <body>
        <h2>Selecting DOM elements</h2>

        <p>
                The employee of the month is <span id="emp">...</span>
        <br>
        <input type="button" value="Change the span value"
               onclick="setEmployeeOfTheMonth()"/>
        Enter your name  <input type="text" id="theName" />
        </p>

        <script>
           function setEmployeeOfTheMonth(){

                   var mySpan = document.getElementById("emp");

                   var empName= document.getElementsByTagName("input")[1];

                   mySpan.firstChild.nodeValue= empName.value;

                }
        </script>

        </body>
</html>

Note the input field of type button, which includes the onclick property that corresponds to the click event. When the user clicks on the button, the browser dispatched click event, and calls the JavaScript function setEmployeeOfTheMonth(). The latter queries the DOM and finds the reference to the emp by calling the method getElementBuId(). After that, the method getElementByTagName() is called trying to find all the references to the HTML <input> elements. This methods returns an array cause there could be more than one element with the same tag name on a page, which explains the use of array notation. The first <input> element is a button and the second is the text field we’re interested in. Remember that arrays in JavaScript have zero-based indexes. [FIG2-21] shows the Web page after the user entered the name Mary and pressed the button.

images/fig_02_21.jpg
Figure 21. Changing the content of the HTML <span> element

While manipulating the content of your Web page you may you may need to traverse the DOM tree. The code example below shows you an HTML document that includes JavaScript that walks the DOM and prints the name of each node. If a node has children, the recursive function walkTheDOM() will visit each child.

<!DOCTYPE html>
<html>
        <head>
                <meta charset="utf-8" />
        </head>

    <body>
     <h1>WalkTheDom.html</h1>

     <p>
        Enter your name: <input type="text"
                                name="customerName" id="custName" />
     </p>

     <input type="button" value="Walk the DOM"
                          onclick="walkTheDOM(document.body, processNode)"/>

     <script>
                function walkTheDOM(node, processNode){

                   processNode(node)
                    node = node.firstChild;

                              while(node){
                                 // call wakTheDOM recursively for each child
                                 walkTheDOM(node,processNode);
                                 node = node.nextSibling;
                              }
            }

         function processNode(node){
            // the real code for node processing goes here

                console.log("The current node name is "+  node.nodeName);
         }
      </script>
    </body>
</html>

Our function processNode() just prints the name of the current node, but you could implement any code that your Web application requires. Run this code in different browsers and check the output on the JavaScript console. [FIG2-22] depicts two snapshots taken in the F12 Developer Tools in Internet Explorer (left) and FIrebug running in Firefox (right).

images/fig_02_22.jpg
Figure 22. Traversing the DOM in Firefox

While some of the output is self-explanatory, there is a number of #text nodes that you won’t find in the code sample above. Unfortunately, Web browsers treat whitespaces differently, and inserts different number of text nodes in the DOM representing whitespaces found in the HTML document. So you’ll be better off using one of the JavaScript frameworks for traversing the DOM cross-browser way. For example, JQuery framework’s API for DOM traversing is listed at http://bit.ly/WXj2r2.

Styling Web Pages with CSS

CSS stands for Cascading Style Sheets. During the last 15 years several CSS specifications reached the level of Recommendation by W3C: CSS Level 1, 2, and 2.1. The latest CSS Level 3 (a.k.a. CSS3) adds new features to CSS 2.1 module by module, which are listed at http://www.w3.org/Style/CSS/current-work.

Tip You can find CSS tutorial as well as tons of other learning resources at webplatform.org.

You can include CSS into a Web page either by linking to separate files using the HTML tag <link> or by in-lining the styles with the tag <style>. For example, if CSS is located in the file mystyles.css in the folder css add the following tag to HTML:

<link rel="stylesheet" type="text/css" href="css/mystyles.css" media="all">

The <link> tag allows specifying the media where specific css file has to be used. For example, you can have one CSS file for smartphones and another one for tablets. We’ll discuss this in detail in the section on media queries in Chapter 11.

You should put this tag in the section of your HTML before any JavaScript code to make sure that they stiles are loaded before the content of the Web page.

Placing the @import attribute inside the <style> tag allows to include styles located elsewhere:

<style>
   @import url (css/contactus.css)
</style>

What’s the best way of including CSS in HTML? Keeping CSS in multiple files separately from HTML and JavaScript makes the code more readable and reusable. On the other hand, if your Web site has consists of many files, the Web browser will have to make multiple round trips to your server just to load all resources required by the HTML document, which can worsen the responsiveness of your Web application.

HTML documents are often prettyfied by using CSS class selectors, and you can switch them programmatically with JavaScript. Imagine that a <style> section has the following definition of two class selectors badStyle and niceStile:

   <style>
         .badStyle{
        font-family: Verdana;
        font-size:small;
        color:navy;
        background-color:red;
    }

    .niceStyle{
        font-family: Verdana;
        font-size:large;
        font-style:italic;
        color:gray;
        background-color:green;
    }
  </style>

Any of these class selectors can be used by one or more HTML elements, for example

<div id="header" class="badStyle">
   <h1>This is my header</h1>
</div>

Imagine that some important event has happened and the appearance the <div> styled as badStyle should programmatically change to <niceStyle>. In this case we need to find the badStyle element(s) first and change their style. The method getElementsByClassName() returns a set of elements that have the specified class name, and since our HTML has only one such element, the JavaScript will use the element zero from such set:

          document.getElementsByClassName("badStyle")[0].className="niceStyle";

The next example will illustrate adding a new element to the DOM. On click of a button the code below dynamically creates an instance of type img and then assigns the location of the image to its src element. In a similar way we could have assigned values to any other attributes of the img element like width, height, or alt. The method appendChild() is applied to the <body> container, but it could be any other container that exists on the DOM.

<!DOCTYPE html>
<html>
        <head>
                <meta charset="utf-8" />
        </head>

    <body>
     <h2>Employee of the month</h2>
        <p>
             <input type="button" value="Show me"
                    onclick="setEmployeeOfTheMonth()"/>
        </p>

     <script>

         function setEmployeeOfTheMonth(){

           // Create an image and add it to the <body> element
           var empImage=document.createElement("img");
                   empImage.setAttribute('src','resources/images/employee.jpg');
                   document.body.appendChild(empImage);
                }

     </script>
    </body>
</html>
Tip Some HTML elements like <div> or <span> have contain other elements (children), and if you need to change their content use their property innerHTML. For example, to delete the entire content of the document body just do this: document.body.innerHTML="".

If you run this example and click on the button "Show me" you’ll see an image of the employee of the month added to the <body> section of the HTML document as shown on [FIG2-23].

images/fig_02_23.jpg
Figure 23. After clicking the button "Show me"

DOM Events

Web browser will notify your application when some changes or interactions occur. In such cases the browser will dispatch an appropriate event, for example load, unload, mousemove, click, keydown etc. When the Web page finished loading the browser will dispatch the load event. When the user will click on the button on a Web page the click event will be dispatched. A Web developer needs to provide JavaScript code that will react on the events important to the application. The browser events will occur regardless of if you provided the code to handle them or not. It’s important to understand some terms related to event processing.

An event handler (a.k.a. event listener) is a JavaScript code you want to be called as a response to this event. The last code sample from the previous section was processing the click event on the button "Show me" as follows: onclick="setEmployeeOfTheMonth()".

Tip Each HTML element has a certain number of predefined event attributes, which start with the prefix on followed by the name of the event. For example onclick is an event attribute that you can use for specifying the handler for the click event. You can find out what event attributes are available in the online document titled Document Object Model Events.

The preferred way of adding event listener was introduced in the DOM Level 2 specification back in 2000. You should find the HTML element in the DOM, and then assign the event listener to it by calling the method addEventListener(). For example:

document.getElementById("myButton").addEventListener("click", setEmployeeOfTheMonth);

The advantage of using of such programmatic assignment of event listeners is that this can be done for all controls in a in a central place, for example in a JavaScript function that runs immediately after the Web page completes loading. Another advantage is that you can programmatically remove the event listener if it’s not needed any longer by invoking removeEventListener(). The following example is a re-write of the last example from the previous section.

<!DOCTYPE html>
<html>
        <head>
                <meta charset="utf-8" />
        </head>

    <body>
     <h2>Employee of the month</h2>
        <p>
             <input type="button" value="Show me" id="myButton"/> <!-- 1 -->
        </p>

     <script>
         window.onload=function(){         // 2
                document.getElementById("myButton").addEventListener("click",
                                                      setEmployeeOfTheMonth);
         }

         function setEmployeeOfTheMonth(){

           // Create an image and add it to the <body> element
           var empImage=document.createElement("img");
                   empImage.setAttribute('src','resources/images/employee.jpg');
                   document.body.appendChild(empImage);

                 document.getElementById("myButton").removeEventListener("click",
                                                 setEmployeeOfTheMonth); // 3
                }

     </script>
    </body>
</html>
1 Compare this button with the one from the previous section: the event handler is removed, but it has an ID now.
2 When the Web page completes loading, a load event is dispatched and the function attached to the event attribute onload assigns the event handler for the button click event. Note that we are passing the callback setEmployeeOfTheMonth as the second argument of the addEventListener()
3 Removing the event listener after the image of the employee of the month has been added. Without this line each click on the button would add to the Web page yet another copy of the same image.

Each event goes through three different phases: Capture, Target, and Bubble. It’s easier to explain this concept by example. Imagine that a button is located inside the <div>, which is located inside the <body> container. When you click on the button, the event travels to the button through all enclosing containers, and this is the capture phase. You can intercept the event at one of these containers even before it reached the button if need be. For example, your application logic may need to prevent the button from being clicked if certain condition occurs.

Then event reaches the button, and it’s a target phase. After the event is handled by the button’s click handler, the event bubbles up through the enclosing containers, and this is the bubble phase. you can create listeners and handle this event after the button finished its processing at the target phase. The next code sample is based on the previous one, but it demonstrates the event processing in all three phases.

Note that if your event handler function is declared with the event parameter, it’ll receive the Event object, which contains a number of useful parameters. For more information refer to the "Document Object Model Events" online.

<!DOCTYPE html>
<html>
        <head>
                <meta charset="utf-8" />
        </head>

    <body>
     <h2>Employee of the month</h2>
        <div id="myDiv">
             <input type="button" value="Show me" id="myButton"/>
        </div>

     <script>
         window.onload=function(){
                document.getElementById("myButton").addEventListener("click",
                                                          setEmployeeOfTheMonth);

                document.getElementById("myDiv").addEventListener("click",
                                                          processDivBefore, true); // 1
                document.getElementById("myButton").addEventListener("click",
                                                          processDivAfter);

         }

         function setEmployeeOfTheMonth(){

           console.log("Got the click event in target phase");

           // Create an image and add it to the <body> element
           var empImage=document.createElement("img");
                   empImage.setAttribute('src','resources/images/employee.jpg');
                   document.body.appendChild(empImage);

                 document.getElementById("myButton").removeEventListener("click",
                                                              setEmployeeOfTheMonth);
                }

         function processDivBefore(evt){
                console.log("Intercepted the click event in capture phase");

                // Cancel the click event so the button won't get it

                // if (evt.preventDefault) evt.preventDefault();        2
                // if (evt.stopPropagation) evt.stopPropagation();
         }

         function processDivAfter(){
                console.log("Got the click event in bubble phase");
         }
     </script>
    </body>
</html>
1 We’ve added two event handler on the <div> level. The first one intercepts the event on the capture phase. When the third argument of addEventListener() is true, this handler will kick in during capture phase.
2 If you uncomment these two lines, the default behavior if the click event will be cancelled and it won’t reach the button at all. Unfortunately, browsers may have different method implementing prevent default functionality hence additional if-statements are needed.

Running the above example will cause the following output in the JavaScript console:

Intercepted the click event in capture phase
Got the click event in target phase
Got the click event in bubble phase
Tip The Microsoft’s Web browsers Internet Explorer 8 and below didn’t implement the W3C DOM Level 3 event model - they handled events differently. You can read more on the subject at this MSDN article http://bit.ly/anZZgZ.

Summary

This chapter was covering the JavaScript language constructs that any professional Web developer should know. A smaller portion of this chapter was illustrating how to combine JavaScript, HTML, and CSS. There are lots of online resources and books cover just the HTML markup and CSS, and you’ll definitely need to spend more time mastering details of the Web instruments. Starting from the next chapter we’ll be working on the Save Sick Child application, which will help you in better understanding of how these ingredients of HTML5 work together and compliment each other.

Chapter 3. Mocking Up the Application «Save Sick Child»

The time has come to start working on our Web application Save Sick Child. It’s going to be a Web site that will supports donations to sick children, show some video, integrate the Google maps, and include the online auction. The goal is to gradually build all the functionality of the Web site while explaining each step of the way and giving you the reasons why we are building it the way we do. By the end of this chapter the Web design and the first prototype of the Save Sick Child site will be ready.

The proliferation mobile devices, Internet connectivity and Web applications require new skills for development of what was known as boring-looking enterprise applications. In the past, development of the user interface of most of the software applications was done by developers to the best of their design abilities: a couple of buttons here, a grid there, a gray background. The business users were happy cause they did not see any better. The application delivers the data – what else to wish for? Enterprise business users used to be happy with whatever UI were given to them as long as the application helped them to take care of their business.

But todays business users are spoiled by nice looking consumers applications and more often than not new development starts with inviting a Web designer who should create a prototype of the future application. We’ve seen excellent (from the UI perspective) functional specificatoins for financial applications made by professional designers. Business users slowly but surely become first-class citizens! The trend is clear: developer’s art does not cut it anymore. You need to hire a professional Web designer for your next Web application. The software developers are not overly familiar with the tools that Web designers are using. This chapter should raise the curtain on the designers role in creating the UI for a Web application.

Our Web designer, let’s call him Alex, is ready to start working on the mockup (a.k.a. wireframes) - a set of images depicting various views of our Save Sick Child application. We expect him to deliver images with comments that would briefly explain what should change in a view if a user will make a certain action, e.g. clicks on the button. You can also think of a UI of an application as a set of states, and the user’s action result in your application’s transition from one state to the other. As nerds and mathematicians say UI of your application is a finite state machine", which at any given point of time is in one of the finite number of states, for example, in the view state Donate Form.

Mobile First?

While starting working on the design of the new Web application keep in mind that most likely some users will access it from mobile devices. Will the proposed UI look good on the mobile devices with smaller screens? Some people suggest using so-called "Mobile First" approach. For example, take the geographical location services. The users of iPhones and Android based devices are used to the fact that they can find the closest restaurant or a gas station based on their current location. Do you know that location feature can be available on the desktops too? Google maps API can find the location of the user’s desktop based on its IP address - it won’t be as precise as with the smartphones but it may be good enough. So why not plan for adding this feature to all versions of your Web application? Finding a sick child located in your region doesn’t have to be as precise as GPS.

Or let’s consider pointing devices. At the time of this writing, vast majority of the desktop users work with pixel-perfect mouse pointers or track pads. SmartPhone or tablet users work with fingers. One finger touch can cover a square with 100 pixels. The CNN site shows lots of news links located very close to each other on the screen. A finger may cover more than one link, and Android devices offer you a larger popup allowing you to select the link you really want to touch. Having the "Mobile first" state of mind doesn’t mean that CNN would need to keep the larger distance between the links for all the users. But this means that they should foresee the issues or innovate using the features offered by modern mobile devices.

In Chapter 11 we’ll discuss the responsive design techniques that allow to create the UI for Web applications that automatically re-allocate the screen content based on the screen size of the user’s device. Although this chapter is about the desktop version of the Sick Child Web application, its screen will consist of several rectangular areas that can be allocated differently (or even hidden) on smartphones or tablets.

One of the constraints that the mobile users have is the relatively slow speed of the mobile Internet. This means that even though your desktop users will use fast LAN connection lines, your Web application has to be modularized and only the minimal number modules has to be loaded initially. Often mobile providers charge the user based on the amount of consumed data too.

The chances are slim that the desktop users will lose the Internet connection for a long period of time. On the other hand, the mobile users may stay in the area with no or spotty connection. In this case the "Mobile First" thinking can lead to introducing an offline mode with limited functionality.

Thinking upfront of the minimal content to be displayed on a small mobile screens may force you to change the design of the desktop Web pages too. In our sample Save Sick Child application we need to make sure that there is a space for the Donate button even on the smallest devices.

Introducing Balsamiq Mockups

Visualize a project owner talking to Alex in a cafeteria, and Alex is drawing sketches of the future Web site on a napkin. Well, in the 21st Century he’ll use an electronic napkin so to speak - an excellent prototyping tool called Balsamiq Mockups. This easy to use program gives you a working area where you create a mockup of your future Web application by dragging and dropping the required UI components from the toolbar onto the image of the Web page (see [FIG3-1]).

image
Figure 24. The working area of Balsamiq Mockups
Tip If you can’t find the required image in Balsamiq’s library, add your own by dragging and dropping it onto the top toolbar. For example, the mockup in Chapter 11 uses our images of the iPhone that we’ve added to Balsamiq assets.

When the prototype is done, it can be saved as an image and sent to the project owner. Another option is to export the Balsamiq project into XML, and if both the project owner and Web designer have Balsamiq installed, they can work on the prototype in collaboration. For example, the designer exports the current states of the project, the owner imports it and makes corrections or comments, then exports it again and sends it back to the designer.

The Project Owner Talks to a Web Designer

During the first meeting Alex talks to the project owner discussing the required functionality and then creates the UI to be implemented by Web developers. The artifacts produced by the designer vary depending on the qualifications of the designer. This can be a set of images representing different states of the UI with little callouts explaining the navigation of the application. If the Web designer is familiar with HTML and CSS, developers may get a working prototype in the form of HTML and CSS files, and this is exactly what Alex will create by the end of this chapter.

Our project owner said to Alex: "The Save Sick Child Web site should allow people to make donations to sick children. The users should be able to find these children by specifying a geographical area on the map. The site should be integrated with a payment system, include a video player and display statistics about the donors and recipients. The site should include an online auction with proceeds going to charity. We’ll start working on the desktop version of this site first, but your future mockup should include three versions of the UI supporting desktops, tablets, and smartphones".

After the meeting Alex launched Balsamiq and started to work. He decided that the main window will consist of four areas laid out vertically:

  1. The header with the logo and several navigation buttons

  2. The main area with the Donate support plus the video player

  3. The area with the Find Local Kid, statistics, and charts.

  4. The footer with several house-holding links plus the icons for Twitter and FaceBook.

The First Mockups

The first deliverable of our Web designer (see [FIG3-2] and [FIG3-3]) depicted two states of the UI: before and after clicking the button Donate Now. The Web designer suggested that on the button click the Video Player would turn into a small button revealing the donation form.

images/fig_03_02.png
Figure 25. The main view before clicking Donate Now. Take 1.
images/fig_03_03.png
Figure 26. The main view after clicking Donate Now. Take 1.

The project owner suggested that turning the video into a Donate button may not be a the best solution. We shouldn’t forget that the main goal of this application is collecting donation, so they decided to keep the user’s attention on the button Donate and move the video player to the lower portion of the window. The next version of the mockup looks as shown in [FIG3-4] and [FIG3-5]. The latter shows different UI states should the user decide to log in.

images/fig_03_04.png
Figure 27. The main view. Take 2.

Next comes authorization. The view states in this process are: 1. Not Logged On 2. The Login Form 3. Wrong ID/Password 4. Forgot Password 5. Successfully Logged On

The Web designer has to create a mockup for each of these states. The project owner will review them and return them back to Alex with some comments. [FIG3-5] illustrates selected views from authorization. Due to some miscommunication the Web designer assumed that unless the user log on to the application, she won’t be able to access the Web site. This is clearly wrong as the process of making donations has to be as easy as possible, and forcing the donor to log on may scare some people away.

images/fig_03_05.png
Figure 28. Selected authorization UI states

From Mockup to HTML Prototype

We are lucky - Alex knows HTML and CSS. He’s ready to turn the still mockups into the first working prototype. It’ll use only hard-coded data but the layout of the site will be done in CSS and we’ll use HTML5 markup.

Note Authors of this book assume that the users of our "Save Sick Child" site work with the modern versions of Web browsers (two year old or younger). The real world Web developers need to deal with finding workarounds to the unsupported CSS or HTML5 features in the old browsers, but modern IDE generate HTML5 boilerplate code that include large CSS files providing different solutions to older browsers. JavaScript frameworks implement workaround for features unsupported by old browsers too, so we don’t want to clutter the text providing several versions of the code just to make book samples work in outdated browsers.

This chapter will include a lot of sample code illustrating how the UI is gradually being built. We’ve created a number of Aptana projects and each of them can be run independently. Create a new workspace in Aptana Studia (File | Switch Workspace) and import all these projects from ch2.zip in one shot (File | Import | General | Exiting projects into Workspace ). After that you’ll be able to run each of these examples by right-clicking on the index.html and selecting Run as | JavaSecript Web Application.

Adding Styles With CSS

We’ve been using some CSS in short code samples in Chapter 2, and now let’s apply styles to make Save Sick Child look as in the mockup. We’ve been using some CSS in short code samples from Chapter 2, and now it’s time to apply styles to make Save Sick Child look as in the mockup.

Test-Driven Development with JavaScript

Idea: No more blog posts on Backbone.js or other JS frameworks without showing tests. Testing JS needs to be a bigger deal than it is.

http://twitter.com/bphogan/status/194856922208407552
— @bphogan

The chapter starts with a brief overview of available test frameworks. Then, it explains how to set up a new Save a Child project in the IDE using selected test framework.

Chapter 8. Replacing HTTP with WebSockets

Shaving off hundreds of bytes of HTTP overhead and reducing the latency from 150ms to 50 ms makes WebSocket worthwhile considering for any application.

— http://ietf.org/mail-archive/web/hybi/current/msg00784.html

This chapter starts with introducing of existing "legacy" options for creating interactive Web applications. After that we’re going to introduce Server-Sent Events (SSE) and WebSockets, which are included in HTML5 specification.

We’re going to implement monitoring of the fund-raising events and an interactive auction for our Save Sick Child application using WebSockets and Server-Sent Events. We’ll use Wireshark, a network monitoring tool, to see benefits of using WebSockets protocol.

All server-side functionality supporting this chapter is written in Java, using the Project «Tyrus» with latest Glassfish builds. If you don’t know Java, just treat this server side setup as a service that supports WebSockets. For Java developers interested in diving into the server-side, we’ll provide the source code and brief comments as a part of the code samples that come with this book.

TODO: Show the server-side data push with Server-Sent Events and WebSockets. Compare them. Do a brief overview of the Socket.IO library. Comparing sending data using WebSockets data throughput with the HTTP data push will be demonstrated in Chapter 4.

Near Realtime Applications With HTTP

The HTTP protocol is the lingua franca of today’s Web applications, where client-server communications are based on the request-response paradigm. On the low level, Web browsers establish a TCP/IP connection for each HTTP request-response session. Every time when the browser needs to send data to server and get response back the browser re-establish the TCP/IP connection. So to implement interactiveness in your application currently, there are 3 basic options that developer has to use today to satisfy the real-time client-server communication requirements. Basically, that options provide hacks on top of half-duplex HTTP protocol to simulate real-time behavior. Lets discuss each of them.

Short Polling

With short polling, your client code sends requests to the server every N seconds. The response is «empty» if there is no update as illustrated in Figure 8-1. Visualize a child seating on back seat of your car and asking, "Are we where?" every minute. And you’re politely replying "Not just yet" - compare it to a empty server response. There is no valuable payload for this kid, but she’s still receiving some "metadata". HTTP polling does the same thing that generates verbose HTTP response headers sending empty payload. Let alone destructing the driver (think the server) from performing other responsibilities.

image

Figure 8-1 Short polling

Long Polling

Long polling starts similarly to short polling: the client sends HTTP request to server. But in this case instead of sending an empty response (as in case with short polling), server waits till the data for the client becomes available. If the requested information is not available after the specified timeout, the server server sends an empty response to the client and closes the connection.

We’ll give you one more analogy to compare short and long polling. Imagine a party at the top floor of a building equipped with a smart elevator that goes up every minute and opens the door just in case if one of the guests wants to go down to smoke a cigarette. If no one enters the elevator, it goes to the ground level and in 60 seconds goes up again. This is the short polling scenario. But if this elevator would go up, and waited till someone would actually decided to go down, then we could call it a long polling mode.

From HTTP specification perspective this "hack" is legit: long polling server behavior indistinguishable from the «slow» server. That is why this technique also referred as "Hanging GET". If you see an online auction that automatically modifies the prices as people bid on the item it looks as if the server pushes the data to you. But most likely, this functionality was implemented using long polling, which is not a real server-side data push, but its emulation.

image

Figure 8-2 Long polling

TODO Compare pros and cons of long vs short polling

HTTP Streaming

Client sends the request, server wait for events and streams multipart/chunked response, and then waits for the events. The server pushes the data to the client pretending that the response never ends. The response is continually appended by the server, usually with <script> what gets executed even after the HTTP DOM object is ready

image

Figure 8-3 HTTP streaming

Polling and streaming can be used as a fall-back for legacy browsers that don’t support the modern HTML5 APIs Server-Sent Events and WebSockets.

Server-Sent Events

Before diving into WebSockets protocol lets get familiar with the standardized way of implementing Server-Sent Events. W3C introduces new browsers API and - EventSource object. SSE allows to subscribe to remote server events arriving in the form of DOM events. The following code snippet shows the JavaScript code that can be used in a Web browser.

var source;
if( !! window.EventSource) {
    source = new EventSource('/donate_web/api/donations/events');  // 1
} else {
    console.log("sse not supported")
}

source.addEventListener('open', function(e) {                   // 2
    // Connection was opened.
}, false);

source.addEventListener('create', function(e) {                 // 3
    console.log(e.data);
}, false);

source.addEventListener('update', function(e) {                 // 4
    console.log(e.data);
}, false);

source.addEventListener('error', function(e) {
    if(e.readyState == EventSource.CLOSED) {
        // Connection was closed.
    }
}, false);
1 Create new EventSource object. At this point the browser will sends the GET request to the specified server-side endpoint to register itself on the server
2 Add handlers for the open and error events
3 Handle messages in create events
4 Handle messages in update events

Using SSE is a good technique for the use cases when the client doesn’t need to send the data to the server. In the above example the server sends two types of events create and update to notify subscribed clients about changing information about donation data so connected clients can monitor fund-raising process. We can create as many named-events as we want. This technique is still HTTP-based, and it requires the server’s support of a combination of HTTP 1.1 keep-alive connections and the text/event-stream content type. The overhead is minimal - instead of hundreds of bytes, the server sends only tens of bytes.

Introducing WebSockets

WebSockets is a bi-directional full-duplex socket-based protocol. The idea behind WebSockets is straightforward:

  • Establish a socket connection between the client and the server using HTTP for the initial handshake.

  • Switch the communication protocol from HTTP to direct socket-based protocol

  • Send messages in both directions simultaneously (full duplex).

  • Send messages independently. No request-response model. Both the server and the client can initiate data transmission which enables real server-push

  • Accordungly, both the server and the client can initiate disconnect.

We will explain each of this statements later in this chapter while introducing WebSocket API.

IETF RFC 6455 Protocol

WebSocket introduces the new protocol URI’s: ws and wss for secured web-socket connection.

WebSockets Interface

To define an abstract Web socket interface the expert group uses Interface Description Language

[Constructor(DOMString url, optional (DOMString or DOMString[]) protocols)] //1
interface WebSocket : EventTarget {
  readonly attribute DOMString url;

  // ready state
  const unsigned short CONNECTING = 0;
  const unsigned short OPEN = 1;
  const unsigned short CLOSING = 2;
  const unsigned short CLOSED = 3;
  readonly attribute unsigned short readyState;
  readonly attribute unsigned long bufferedAmount;

  // networking
  [TreatNonCallableAsNull] attribute Function? onopen;
  [TreatNonCallableAsNull] attribute Function? onerror;
  [TreatNonCallableAsNull] attribute Function? onclose;
  readonly attribute DOMString extensions;
  readonly attribute DOMString protocol;
  void close([Clamp] optional unsigned short code, optional DOMString reason);

  // messaging
  [TreatNonCallableAsNull] attribute Function? onmessage;
           attribute DOMString binaryType;
  void send(DOMString data);
  void send(ArrayBufferView data);
  void send(Blob data);
};
1 The constructor requires an endpoint URI and optional sub-protocols name.
Client-Side API

After the introduction of the WebSockets interface lets see how the client’s JavaScript can use it.

var ws;
if(window.WebSocket) {    // 1
    console.log("WebSocket object is supported in your browser");   

    ws = new WebSocket("ws://www.websocket.org/echo"); // 2
    ws.onopen = function() { console.log("onopen"); 
    };  // 3 
     
    ws.onmessage = function(e) {
        console.log("echo from server : " + e.data);  // 4
    };

    ws.onclose = function() { // 5
        output("onclose"); 
    };
    ws.onerror = function() { output("onerror");  // 6
    };

} else {
    output("WebSocket object is not supported in your browser");
}
1 Check if the WebSocket object is supported by the browser.
2 Instantiate the new WebSocket object with passing endpoint URI as constructor parameter.
3 Set event handlers for open, message, close events.
4 e.data property of the message event contains the received message.
5 handle closing connection …
6 … and errors
WebSockets Handshake

Handshake upgrades the connection from HTTP to the WebSockets protocol. It’s an upgrade to a message based communication. We will discuss messages (a.k.a. frames) later in this chapter. Why upgrading from HTTP instead of starting with the TCP as a protocol in the first place? The reason is that the WebSockets operates on the same ports (80 and 443) as HTTP and HTTPS do. It’s an advantage because all ports under 1024 are privileged, and they are handled differently than non privileged ones.

For instance, on Linux systems only the user with root privileges can create a socket on such ports. WebSockets use the same port as HTTP/HTTPS and it make this much more interesting. Another example would be the Flash Player socket policy system that will attempt to connect to port 843 to get the authorization information.

We have to tunnel our communication through the HTTP because arbitrary socket connections may not be allowed by the various firewalls for security or scalability reasons. In most of the cases, HTTP connections via ports 80 or 443 are allowed where the TCP socket connections are not. Also many corporate networks only allow certain ports outgoing. And HTTP/HTTPS ports are usually included in so called white lists.

The protocol upgrade is initiated by the client request, which also transmits a special key with the upgrade request. The server processes this request and send back a confirmation for the upgrade. This ensures that a WebSocket connection cannot be established with an endpoint that is not aware of the WebSockets protocol. Here is what the handshake looks can like in the client’s request:

    GET HTTP/1.1
    Upgrade: websocket
    Connection: Upgrade
    Host: echo.websocket.org
    Origin: http://www.websocket.org
    Sec-WebSocket-Key: i9ri+AfOgSsKwUlmLjIkGA==
    Sec-WebSocket-Version: 13

This client sends the GET request for the protocol upgrade. The Sec-WebSocket_Key is just a set of random bytes. The server takes these bytes and appends to it a special Global Unique Identifier (GUID) string 258EAFA5-E914-47DA-95CA-C5AB0DC85B11, then creates theSecure Hash Algorithm SHA1 hash from it followed by the base64 encoding. The resulting string of bytes needs to be used by both the server and the client, and it’s unlikely that this string will be used by the network endpoints that do not understand the WebSockets protocol. Then this value would be copieded in the Sec-WebSocket-Accept header field. When the server has computed the value it can send the response back confirming the protocol upgrade.

    HTTP/1.1 101 Web Socket Protocol Handshake
    Upgrade: WebSocket
    Connection: Upgrade
    Sec-WebSocket-Accept: Qz9Mp4/YtIjPccdpbvFEm17G8bs=
    Access-Control-Allow-Origin: http://www.websocket.org

The WebSockets protocol uses the 400 Bad Request error to signal the missing upgrade. The handshake can also include a protocol request and the WebSocket version information but you can’t include arbitrary other headers. We can’t transmit the authorization information. There are two ways around this. You can either transmit the authorization information as the first request (e.g. unique clientId can be passed as part of the HTTP response header or HTML wrapper) or put it into the URL as a query parameter during the initial handshake. Consider the following example.

var clientId = AppContext.getClientId();                        // 1
ws = new WebSocket("ws://www.websocket.org/echo/"+clientID); // 2
1 Here we’re getting clientId value from the AppContext singleton object.
2 We’re connecting to the WebSockets endpoint with an extra URI parameter which will be stored on server for future interactions.

Because WebSockets protocol creates a bi-directional (socket-to-socket) connection server has access to conversation session associated with the new web socket connection. This session can be associated with clientId and be stored on server.

Note There is no limit to the number of established WebSocket connections a client can have with a single remote host. Servers can refuse to accept connections from hosts/IP addresses with an excessive number of existing connections or disconnect resource-hogging connections in case of high data load.
The WebSocket frame anatomy

In this section we’re going to explore how the WebSocket data transfer works. The WebSocket is not a stream based protocol like TCP - it’s message based. The difference is that with TCP a program sends the bytes and has to ensure that the end of a message can be recognized. The WebSocket specification makes it easier because it puts a frame around everything. It’s easy to do from the JavaScript on the client, but it’s harder to handle in the server side code because it needs to wrap everything in frames. The frame can look like this:

+-+-+-+-+-------+-+-------------+-------------------------------+
0                   1                   2                   3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-------+-+-------------+-------------------------------+
|F|R|R|R| opcode|M| Payload len |    Extended payload length    |
|I|S|S|S|  (4)  |A|     (7)     |             (16/64)           |
|N|V|V|V|       |S|             |   (if payload len==126/127)   |
| |1|2|3|       |K|             |                               |
+-+-+-+-+-------+-+-------------+ - - - - - - - - - - - - - - - +
|     Extended payload length continued, if payload len == 127  |
+ - - - - - - - - - - - - - - - +-------------------------------+
|                               |Masking-key, if MASK set to 1  |
+-------------------------------+-------------------------------+
| Masking-key (continued)       |          Payload Data         |
+-------------------------------- - - - - - - - - - - - - - - - +
:                     Payload Data continued ...                :
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
|                     Payload Data continued ...                |
+---------------------------------------------------------------+
  • FIN (1 bit)

This bit indicates if this frame is the final frame that makes up the message. Most of the time the message fits into a single frame and this bit will always be set.

  • RSV1, RSV2, RSV3 (1 bit each)

These bits are the reserved for future protocol changes and improvements. They must contain zeros as they are not being used at this time.

  • opcode (4 bits)

The frame type is defined using opcode. Here most used opcodes:
  • 0x00 This frame continues the payload from the last.

  • 0x01 This frame includes utf-8 text data.

  • 0x02 This frame includes binary data.

  • 0x08 This frame terminates the connection

  • 0x09 This frame is a Ping.

  • 0x10 This frame is a Pong.

    • mask (1 bit)

This indicates if the frame is masked.

Note The client must mask all the frames being sent to the server. The server must close the connection upon receiving a frame that is not masked. The server must not mask any frames that it sends to the client. The client must close a connection if it detects a masked frame. In that case of such error, client or server can send Close frame with 1002 status code - protocol error.
  • payload_len (7 bits, 7+16 bits, or 7+64 bits)

The length of the payload. WebSocket frames come in the following length brackets: 0-125 indicate the length of the payload. 126 means that the following two bytes indicate the length. ** 127 means the next 8 bytes indicate the length.

  • masking-key (32 bits)

This key is used to XOR the payload with.

  • payload

This indicates the actual masked data. The length of block is defined in the payload_len bits.

more TBD

The Heartbeats

Certain things like transparent and explicit proxy servers or a content-filtering hardware can terminate the idle connections or a remote side could go down. Only on the next send your program can realize that something went wrong. With WebSockets the browser can send the ping opcode 0x9 at any time to ask the other side to pong back (the opcode 0xA).

Pings can be sent whenever required, but a pong may sent at server’s discretion. If an endpoint receives a Ping frame and has not yet sent Pong frame(s) in response to the previous Ping frame(s), the endpoint can elect to send a Pong frame for only the most recently processed Ping frame. The Ping frame may contain the application data (can be up to 125 bytes) and Pong must have identical data in message body.

There is no Javascript API to send Ping frames or receive Pongs frames. This is either supported by your browser, or not. There is also no API to enable, configure or detect whether the browser supports and is using Ping/Pong frames.

TODO - Client-side frameworks - Server-side API

WebSocket Use Cases

WebSockets really shine with following applications:

  • Live trading/auctions/sports notifications

  • Controlling medical equipment over the web

  • Chat applications

  • Multi-player online games

  • Real-time updates in social streams

For the "Save Sick Child" application we’re going to use WebSockets to implement an online auction communication layer. The goal is to let individuals and businesses purchase hand-made crafts and arts made by the children. All proceeds will go to help sick children.

Protocols Considerations for Enterprise Applications

The downside: WebSockets specification gives you only the transport, but it doesn’t include the application-level protocol. Developers need to invent the application-specific text or binary protocols. For example, the auction bid has to be presented in a form agreed upon by all application modules. Let’s discuss our options from protocol modeling perspective.

TODO

WebSockets and Proxies

HTTP always supported upgrades, but unfortunately many proxies seem to have ignored that part of the specification. The main reason for that probably is that until WebSockets came around no one was actually using the Upgrade flag.

WebSockets and HTTP 2.0

"I use the metaphor of hammers and screwdrivers. Both tools are indispensable in my workshop…

Use the right tool for the job. In the case of page and object delivery use SPDY. In the case of lightweight or streaming data delivery look to WebSocket."

Stephen Ludin
— Chief Product Architect at Akamai
  • http 2.0, spdy, websockets

  • framed protocols (describe frames)

Part 2: Mobile

Chapter 11. Responsive Design: One Site Fits All

The chapter starts with a brief overview of different approaches to making the Web site to the mobile space. One of the approaches is having only one Web site for all devices. This approach is is called Responsive Design, and we’ll modify the design of the Save Sick Child site to introduce different layouts for the desktop, tablet, and smartphone devices. By the end of this chapter the site Save Sick Child will automatically change its layout based on the user’s device without the losing any functionality.

One Code Base vs. Two

People responsible for developing a Web application that can run on both desktop and mobile platforms usually start with making an important decision: HTML5 or native? This book is not about native applications - we’ll only review the hybrid applications in Chapter 14. But even if a decision was made in the favor of Web platform, the next question is if the desktop and mobile clients will use the same code or not.

If you’ll decide to go with separate versions of the Web applications, the Web server can be configured to perform redirection to the appropriate code. Web servers can do it based on the value of the User-Agent attribute of the HTTP request’s header. For example, the mobile Web browsers of bbc.com deliver the content from different URLs and they look differently (see [FIG11-1] and [FIG11-2]).

images/fig_11_01.jpg
Figure 29. The desktop version of bbc.com

The above version delivers more content that can be allocated nicely on the large desktop monitor or a tablet. But the mobile version minimizes substantially what’s delivered to the client over potentially slower network to be displayed on a small screen.

images/fig_11_02.png
Figure 30. The mobile version of bbc.com

Have you ever tried to share the link of the Web site from your iPhone? It’s so easy! Just press the button and enter the email of the person to share the site with. Go to bbc.com (it’ll be redirected) on your iPhone and share this link with someone. That person will receive the link http://www.bbc.co.uk/mobile/i, and if she’s visit this site from the desktop it won’t look pretty - try to enter this URL in your desktop browser to see for yourself.

In this chapter we’ll discuss how to design Web applications that have one code base for both the mobile and the desktop versions. The Save Sick Child application will have the same code but will present itself differently on desktop and mobile devices using responsive design and CSS media queries. This is not necessarily the better approach to having separate versions as with the bbc.com, but we’ll talk about pros and cons of both approaches.

Maintaining two different versions of the code requires more efforts than maintaining one: you need to have two sets of HTML, CSS, JavaScript, and images. Besides, most likely your Web application will use a third-party JavaScript framework. At some point you may run into a bug and need to upgrade the mobile version to use the latest version of such frameworks, say jQuery. But the desktop version works just fine. In case of having two separate versions of the application you’ll have to either upgrade jQuery and thoroughly test both mobile and desktop versions of Save Sick Child, or live with two different versions of the framework. Responsive design allows to have one version of everything.

On the other hand, with responsive design your users will be downloading unnecessary code - the CSS that include all versions of screen layouts and larger than needed images to be scaled by the Web browser.

Here comes the million dollar question, "When we talk about creating two different versions of the Web application, is it really two, twenty two, or maybe two hundred and twenty two?" How many different mobile devices are there today and will be there tomorrow?

How many User Agents are there

Let’s spend a little more time discussing the HTTP header’s attribute User-Agent that contains information about the user agent originating request. Should you decide to create several versions of the UI based on the value in the User-Agent field, you can refer to the Web site http://useragentstring.com. It lists not two, but hundreds of strings representing possible content of the User-Agent attribute for lots of desktop and mobile devices. For example, [FIG11-3] shows how the User-Agent from the iPhone 5 string is reported and explained by useragentstring.com.

images/fig_11_03.png
Figure 31. The User-Agent String from iPhone 5

It’s impossible to create different layout of your Web application for each user agent.

Chapter 14. Hybrid Applications: HTML + Native API

Both Web and native applications have their pros and cons. Let’s start with some of the examples of the native applications that exist today.

Bank of America’s native mobile application allows you to deposit checks by taking a photo of the front and back sides of the check and entering the amount. At the time of this writing, they support iPhones, Android, Windows phones, and iPads.

Near Field Communication (NFC) technology allows NFC-enabled devices communicate with each other in close distance using radio frequencies. NFC can be used for payments (no need to enter passwords) and data sharing (contacts, photos, et al.). Proliferation of NFC in banking will seriously hurt the credit cards industry. A number of smartphones already support NFC technology (see http://www.nfcworld.com/nfc-phones-list). Add one of the existing fingerprint biometrics solutions, and your mobile phone becomes your wallet.

While native applications have full access to all hardware of the device (e.g. camera, microphone, et al.), they have drawbacks too. For instance, if you want to publish your application at Apple’s App Store you have to submit your application in advance and wait for an approval. If a crucial bug is found in your application, even though if you could fix it in a day, you can’t put a new version in production until it went through an approval process. Back in 2011 Financial Times (FT) decided to stop using their native iOS application because Apple wouldn’t share the data about FT subscribers. Don’t forget that Apple would get their own cut from each FT subscription.

On one hand it’s good to have an ability to publish your latest Web applications on your own servers without the need to ask for a permission. On the other hand, the presence on Apple’s iTunes is a good channel for bringing new customers. The publisher of New York magazine is heavily investing into their native application for iPad but the newer versions of their Web applications are as engaging as their native piers. If you Web application has to be discoverable and visible by search engines, Web application are definitely better.

The hybrid applications promise you to have the best of both worlds. A Web application written in HTML/JavaScript has access to the hardware of the mobile device via a third-party library such as PhoneGap.The PhoneGap recompiles HTML/JavaScript code to create a platform specific application with an embedded Web browser, where your HTML/JavaScript code will run. This embedded browser (a.k.a. Web View) is chrome-less and your application is getting access to full size of the device screen.

The PhoneGap packaging tool takes your HTML/JavaScript/CSS code, compiles it for the required mobile platform and create a native application that has access to the native functionality of hardware, for example, if you need to deploy it under iOS, you’ll get an IPA file, and for deployment on Android devices you’d be getting an APK file. The hybrid applications may be not as fast as the native ones, and the architects responsible for defining mobile enterprise strategy must setting their priorities.

If a particular application will be used only by the employees of the organization who will use limited and defined number of mobile devices, and if making employees productive is the main goal - develop native applications. Start with developing and deploying such an application for the pilot OS (typically iOS 6 or Android 4), and then gradually add support for more  platforms, budget permitting. If you are planning to develop a Web application with relatively simple UI (e.g. Save Sick Child) and have to support a wide variety of unknown consumer devices (e.g. allow people make donation from any device) - develop a HTML5 Web application.

Consider developing a hybrid application for anything in between, and in this chapter we’ll create a hybrid version of our Save Sick Child application with PhoneGap framework. To be more specific, we’ll access the location services of the smartphone and will use the PhoneGap PayPal plugin to process donations.

Tip For current list of available PhoneGap plugins for various mobile platforms visit the github repository at https://github.com/phonegap/phonegap-plugins.

What’s PhoneGap

First of all, PhoneGap is not a competitor of such JavaScript frameworks as jQuery, Ext JS, AngularJS, Ember.js and the like. PhoneGap is a technology for creating an application container can run code written with or without using these frameworks, and its main goal is to provide the JavaScript API for getting access to the hardware of mobile devices as well as the build tool for its subscribers.

Note PhoneGap is a brand own by Adobe. Apache Foundation has an open source project called Cordova, which started from the code donated by Adobe to Apache. Lots of developers from around the world work on Cordova, but Adobe’s using this library to create their own way of compiling and distributing mobile applications, which is branded as PhoneGap. The closest analogy is the Chrome and Safari browsers built on the same open source rendering engine Webkit.